Provide default values for UploadStreamToBlockBlobOptions and refactor UploadStreamToBlockBlob (#167)
* Refactor of UploadStreamToBlockBlobOptions Refactor to remove bugs and extra complexity. * Migrate stream code to own file. Add concurrency. After benchmarking, code was 25% slower without concurrency in azcopy, regardless of buffer sizing. This change introduces back concurrency, but with a much simpler model and still eliminating the the atomic operations. * Update to use io.ReadFull() Adding test. Benchmarks are now on par with the original code. Here is 10 runs using the current azcopy binary and a binary built from changed code: Binary = bins/azcopy_original(run 1) Benchmark 1KiB file: 338.314573ms Benchmark 1MiB file: 484.967288ms Benchmark 10MiB file: 760.810541ms Benchmark 100MiB file: 1.351661794s Benchmark 1GiB file: 10.826069714s Binary = bins/azcopy_original(run 2) Benchmark 1KiB file: 207.941537ms Benchmark 1MiB file: 460.838416ms Benchmark 10MiB file: 760.783836ms Benchmark 100MiB file: 1.501405998s Benchmark 1GiB file: 7.18717018s Binary = bins/azcopy_original(run 3) Benchmark 1KiB file: 212.47363ms Benchmark 1MiB file: 467.623706ms Benchmark 10MiB file: 698.447313ms Benchmark 100MiB file: 1.292167757s Benchmark 1GiB file: 7.637774779s Binary = bins/azcopy_original(run 4) Benchmark 1KiB file: 276.746547ms Benchmark 1MiB file: 465.676606ms Benchmark 10MiB file: 646.126277ms Benchmark 100MiB file: 1.087617614s Benchmark 1GiB file: 6.546629743s Binary = bins/azcopy_original(run 5) Benchmark 1KiB file: 224.753013ms Benchmark 1MiB file: 468.194201ms Benchmark 10MiB file: 658.754858ms Benchmark 100MiB file: 1.287728254s Benchmark 1GiB file: 7.349753091s Binary = bins/azcopy_original(run 6) Benchmark 1KiB file: 215.433224ms Benchmark 1MiB file: 468.2654ms Benchmark 10MiB file: 736.859155ms Benchmark 100MiB file: 1.288282248s Benchmark 1GiB file: 9.901807484s Binary = bins/azcopy_original(run 7) Benchmark 1KiB file: 309.374802ms Benchmark 1MiB file: 466.3705ms Benchmark 10MiB file: 764.919816ms Benchmark 100MiB file: 1.288119942s Benchmark 1GiB file: 12.568692895s Binary = bins/azcopy_original(run 8) Benchmark 1KiB file: 223.696311ms Benchmark 1MiB file: 459.585207ms Benchmark 10MiB file: 861.388787ms Benchmark 100MiB file: 2.001739213s Benchmark 1GiB file: 14.062394287s Binary = bins/azcopy_original(run 9) Benchmark 1KiB file: 213.478124ms Benchmark 1MiB file: 472.516087ms Benchmark 10MiB file: 888.345447ms Benchmark 100MiB file: 1.712670977s Benchmark 1GiB file: 7.351456844s Binary = bins/azcopy_original(run 10) Benchmark 1KiB file: 211.893325ms Benchmark 1MiB file: 461.4607ms Benchmark 10MiB file: 810.622545ms Benchmark 100MiB file: 1.649993952s Benchmark 1GiB file: 12.236548842s Binary = bins/azcopy_changed(run 1) Benchmark 1KiB file: 253.721968ms Benchmark 1MiB file: 498.897549ms Benchmark 10MiB file: 787.010372ms Benchmark 100MiB file: 1.381749395s Benchmark 1GiB file: 10.446411529s Binary = bins/azcopy_changed(run 2) Benchmark 1KiB file: 252.710169ms Benchmark 1MiB file: 531.817803ms Benchmark 10MiB file: 829.688513ms Benchmark 100MiB file: 1.385873084s Benchmark 1GiB file: 8.47119338s Binary = bins/azcopy_changed(run 3) Benchmark 1KiB file: 257.306962ms Benchmark 1MiB file: 505.047536ms Benchmark 10MiB file: 784.31337ms Benchmark 100MiB file: 1.555737854s Benchmark 1GiB file: 8.552681344s Binary = bins/azcopy_changed(run 4) Benchmark 1KiB file: 247.846574ms Benchmark 1MiB file: 497.231545ms Benchmark 10MiB file: 815.651525ms Benchmark 100MiB file: 2.697350445s Benchmark 1GiB file: 7.516749079s Binary = bins/azcopy_changed(run 5) Benchmark 1KiB file: 252.352667ms Benchmark 1MiB file: 501.701337ms Benchmark 10MiB file: 707.436865ms Benchmark 100MiB file: 1.36936469s Benchmark 1GiB file: 9.73502422s Binary = bins/azcopy_changed(run 6) Benchmark 1KiB file: 310.863688ms Benchmark 1MiB file: 502.052735ms Benchmark 10MiB file: 1.002850071s Benchmark 100MiB file: 1.506176604s Benchmark 1GiB file: 11.832881097s Binary = bins/azcopy_changed(run 7) Benchmark 1KiB file: 257.951257ms Benchmark 1MiB file: 504.845129ms Benchmark 10MiB file: 897.192408ms Benchmark 100MiB file: 3.660229033s Benchmark 1GiB file: 8.277701479s Binary = bins/azcopy_changed(run 8) Benchmark 1KiB file: 248.399669ms Benchmark 1MiB file: 510.47592ms Benchmark 10MiB file: 660.498819ms Benchmark 100MiB file: 983.16489ms Benchmark 1GiB file: 9.696608161s Binary = bins/azcopy_changed(run 9) Benchmark 1KiB file: 256.139558ms Benchmark 1MiB file: 509.733119ms Benchmark 10MiB file: 787.046948ms Benchmark 100MiB file: 1.304473257s Benchmark 1GiB file: 10.392113698s Binary = bins/azcopy_changed(run 10) Benchmark 1KiB file: 253.185361ms Benchmark 1MiB file: 500.357929ms Benchmark 10MiB file: 852.302359ms Benchmark 100MiB file: 1.555795815s Benchmark 1GiB file: 9.234134017s * Improve comments, use getErr() instead of old statement, add test for write errors Added some comment fixes. Adding some TODOs. Had an error detection using select that could just use getErr() instead. Wrote support and test for having a write error. * Updates to comments provided by ze * Reduces construction of chunk ids for the commit list, moves azblob_test to azblob azblob_test should be azblob test, allowing access to private types and removing the need for azblob. as a prefix. Could find no reason to make as a seperate package in a non-go standard way. This packages' derivation from the blobstore standard of a new UUID per chunk has merits as discussed with Adele(faster, less memory, possible upload resumes, etc...). So it was decided to keep it. However, wanted to make this easier for us to autoincrement ids and provide the list of IDs to commit instead of recreating them at the end at the cost of CPU we didn't have to spend (we were going to spend the memory anyways). So provided a better way to get the IDs. This change required changes to the tests. Most tests use a single blockID. For those tests we now use a var created on init() that is a UUID+ math.MaxUint32. That allows us to test the maximum value. For others, we now use our id type. This changed one test that was trying to test order, which wasn't necessary. All tests are passing. * Update gomod to import uuid an update of adal * Update go.mod via go tidy command The adal change was because one of the zt tests uses it. It always should have been there and won't cause any change in functionality. errors gets added as an indirecty from check.v1, which it should have always had. This is because check doesn't have a go.mod file. Adds a minimum version of Go compiler 1.13 * Update go.mod * Just the mod updates * Get it back into shape Some git thing on my side, had to get us hand patched back right. Co-authored-by: John Doak <jdoak@janama-2.redmond.corp.microsoft.com> Co-authored-by: John Doak <jdoak@Fan061719.northamerica.corp.microsoft.com>
This commit is contained in:
Родитель
68bdb825c9
Коммит
c0650f8c2c
|
@ -291,3 +291,4 @@ __pycache__/
|
|||
*.xsd.cs
|
||||
|
||||
vendor/
|
||||
*.env
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
package azblob
|
||||
|
||||
import "sync/atomic"
|
||||
|
||||
// AtomicMorpherInt32 identifies a method passed to and invoked by the AtomicMorphInt32 function.
|
||||
// The AtomicMorpher callback is passed a startValue and based on this value it returns
|
||||
// what the new value should be and the result that AtomicMorph should return to its caller.
|
||||
type atomicMorpherInt32 func(startVal int32) (val int32, morphResult interface{})
|
||||
|
||||
const targetAndMorpherMustNotBeNil = "target and morpher must not be nil"
|
||||
|
||||
// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function.
|
||||
func atomicMorphInt32(target *int32, morpher atomicMorpherInt32) interface{} {
|
||||
for {
|
||||
currentVal := atomic.LoadInt32(target)
|
||||
desiredVal, morphResult := morpher(currentVal)
|
||||
if atomic.CompareAndSwapInt32(target, currentVal, desiredVal) {
|
||||
return morphResult
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AtomicMorpherUint32 identifies a method passed to and invoked by the AtomicMorph function.
|
||||
// The AtomicMorpher callback is passed a startValue and based on this value it returns
|
||||
// what the new value should be and the result that AtomicMorph should return to its caller.
|
||||
type atomicMorpherUint32 func(startVal uint32) (val uint32, morphResult interface{})
|
||||
|
||||
// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function.
|
||||
func atomicMorphUint32(target *uint32, morpher atomicMorpherUint32) interface{} {
|
||||
for {
|
||||
currentVal := atomic.LoadUint32(target)
|
||||
desiredVal, morphResult := morpher(currentVal)
|
||||
if atomic.CompareAndSwapUint32(target, currentVal, desiredVal) {
|
||||
return morphResult
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AtomicMorpherUint64 identifies a method passed to and invoked by the AtomicMorphUint64 function.
|
||||
// The AtomicMorpher callback is passed a startValue and based on this value it returns
|
||||
// what the new value should be and the result that AtomicMorph should return to its caller.
|
||||
type atomicMorpherInt64 func(startVal int64) (val int64, morphResult interface{})
|
||||
|
||||
// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function.
|
||||
func atomicMorphInt64(target *int64, morpher atomicMorpherInt64) interface{} {
|
||||
for {
|
||||
currentVal := atomic.LoadInt64(target)
|
||||
desiredVal, morphResult := morpher(currentVal)
|
||||
if atomic.CompareAndSwapInt64(target, currentVal, desiredVal) {
|
||||
return morphResult
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AtomicMorpherUint64 identifies a method passed to and invoked by the AtomicMorphUint64 function.
|
||||
// The AtomicMorpher callback is passed a startValue and based on this value it returns
|
||||
// what the new value should be and the result that AtomicMorph should return to its caller.
|
||||
type atomicMorpherUint64 func(startVal uint64) (val uint64, morphResult interface{})
|
||||
|
||||
// AtomicMorph atomically morphs target in to new value (and result) as indicated bythe AtomicMorpher callback function.
|
||||
func atomicMorphUint64(target *uint64, morpher atomicMorpherUint64) interface{} {
|
||||
for {
|
||||
currentVal := atomic.LoadUint64(target)
|
||||
desiredVal, morphResult := morpher(currentVal)
|
||||
if atomic.CompareAndSwapUint64(target, currentVal, desiredVal) {
|
||||
return morphResult
|
||||
}
|
||||
}
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,228 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
guuid "github.com/google/uuid"
|
||||
)
|
||||
|
||||
// blockWriter provides methods to upload blocks that represent a file to a server and commit them.
|
||||
// This allows us to provide a local implementation that fakes the server for hermetic testing.
|
||||
type blockWriter interface {
|
||||
StageBlock(context.Context, string, io.ReadSeeker, LeaseAccessConditions, []byte) (*BlockBlobStageBlockResponse, error)
|
||||
CommitBlockList(context.Context, []string, BlobHTTPHeaders, Metadata, BlobAccessConditions) (*BlockBlobCommitBlockListResponse, error)
|
||||
}
|
||||
|
||||
// copyFromReader copies a source io.Reader to blob storage using concurrent uploads.
|
||||
// TODO(someone): The existing model provides a buffer size and buffer limit as limiting factors. The buffer size is probably
|
||||
// useless other than needing to be above some number, as the network stack is going to hack up the buffer over some size. The
|
||||
// max buffers is providing a cap on how much memory we use (by multiplying it times the buffer size) and how many go routines can upload
|
||||
// at a time. I think having a single max memory dial would be more efficient. We can choose an internal buffer size that works
|
||||
// well, 4 MiB or 8 MiB, and autoscale to as many goroutines within the memory limit. This gives a single dial to tweak and we can
|
||||
// choose a max value for the memory setting based on internal transfers within Azure (which will give us the maximum throughput model).
|
||||
// We can even provide a utility to dial this number in for customer networks to optimize their copies.
|
||||
func copyFromReader(ctx context.Context, from io.Reader, to blockWriter, o UploadStreamToBlockBlobOptions) (*BlockBlobCommitBlockListResponse, error) {
|
||||
o.defaults()
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
cp := &copier{
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
reader: from,
|
||||
to: to,
|
||||
id: newID(),
|
||||
o: o,
|
||||
ch: make(chan []byte, 1),
|
||||
errCh: make(chan error, 1),
|
||||
buffers: sync.Pool{
|
||||
New: func() interface{} {
|
||||
return make([]byte, o.BufferSize)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Starts the pools of concurrent writers.
|
||||
cp.wg.Add(o.MaxBuffers)
|
||||
for i := 0; i < o.MaxBuffers; i++ {
|
||||
go cp.writer()
|
||||
}
|
||||
|
||||
// Send all our chunks until we get an error.
|
||||
var err error
|
||||
for {
|
||||
if err = cp.sendChunk(); err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
// If the error is not EOF, then we have a problem.
|
||||
if err != nil && !errors.Is(err, io.EOF) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Close out our upload.
|
||||
if err := cp.close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return cp.result, nil
|
||||
}
|
||||
|
||||
// copier streams a file via chunks in parallel from a reader representing a file.
|
||||
// Do not use directly, instead use copyFromReader().
|
||||
type copier struct {
|
||||
// ctx holds the context of a copier. This is normally a faux pas to store a Context in a struct. In this case,
|
||||
// the copier has the lifetime of a function call, so its fine.
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
|
||||
// reader is the source to be written to storage.
|
||||
reader io.Reader
|
||||
// to is the location we are writing our chunks to.
|
||||
to blockWriter
|
||||
|
||||
id *id
|
||||
o UploadStreamToBlockBlobOptions
|
||||
|
||||
// num is the current chunk we are on.
|
||||
num int32
|
||||
// ch is used to pass the next chunk of data from our reader to one of the writers.
|
||||
ch chan []byte
|
||||
// errCh is used to hold the first error from our concurrent writers.
|
||||
errCh chan error
|
||||
// wg provides a count of how many writers we are waiting to finish.
|
||||
wg sync.WaitGroup
|
||||
// buffers provides a pool of chunks that can be reused.
|
||||
buffers sync.Pool
|
||||
|
||||
// result holds the final result from blob storage after we have submitted all chunks.
|
||||
result *BlockBlobCommitBlockListResponse
|
||||
}
|
||||
|
||||
// getErr returns an error by priority. First, if a function set an error, it returns that error. Next, if the Context has an error
|
||||
// it returns that error. Otherwise it is nil. getErr supports only returning an error once per copier.
|
||||
func (c *copier) getErr() error {
|
||||
select {
|
||||
case err := <-c.errCh:
|
||||
return err
|
||||
default:
|
||||
}
|
||||
return c.ctx.Err()
|
||||
}
|
||||
|
||||
// sendChunk reads data from out internal reader, creates a chunk, and sends it to be written via a channel.
|
||||
// sendChunk returns io.EOF when the reader returns an io.EOF or io.ErrUnexpectedEOF.
|
||||
func (c *copier) sendChunk() error {
|
||||
if err := c.getErr(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
chunk := c.buffers.Get().([]byte)
|
||||
n, err := io.ReadFull(c.reader, chunk)
|
||||
chunk = chunk[0:n]
|
||||
switch {
|
||||
case err == nil && n == 0:
|
||||
return nil
|
||||
case err == nil:
|
||||
c.ch <- chunk
|
||||
return nil
|
||||
case err != nil && (err == io.EOF || err == io.ErrUnexpectedEOF) && n == 0:
|
||||
return io.EOF
|
||||
}
|
||||
|
||||
if err == io.EOF || err == io.ErrUnexpectedEOF {
|
||||
c.ch <- chunk
|
||||
return io.EOF
|
||||
}
|
||||
if err := c.getErr(); err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// writer writes chunks sent on a channel.
|
||||
func (c *copier) writer() {
|
||||
defer c.wg.Done()
|
||||
|
||||
for chunk := range c.ch {
|
||||
if err := c.write(chunk); err != nil {
|
||||
if !errors.Is(err, context.Canceled) {
|
||||
select {
|
||||
case c.errCh <- err:
|
||||
c.cancel()
|
||||
default:
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write uploads a chunk to blob storage.
|
||||
func (c *copier) write(chunk []byte) error {
|
||||
defer c.buffers.Put(chunk)
|
||||
|
||||
if err := c.ctx.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err := c.to.StageBlock(c.ctx, c.id.next(), bytes.NewReader(chunk), LeaseAccessConditions{}, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("write error: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// close commits our blocks to blob storage and closes our writer.
|
||||
func (c *copier) close() error {
|
||||
close(c.ch)
|
||||
c.wg.Wait()
|
||||
|
||||
if err := c.getErr(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var err error
|
||||
c.result, err = c.to.CommitBlockList(c.ctx, c.id.issued(), c.o.BlobHTTPHeaders, c.o.Metadata, c.o.AccessConditions)
|
||||
return err
|
||||
}
|
||||
|
||||
// id allows the creation of unique IDs based on UUID4 + an int32. This autoincrements.
|
||||
type id struct {
|
||||
u [64]byte
|
||||
num uint32
|
||||
all []string
|
||||
}
|
||||
|
||||
// newID constructs a new id.
|
||||
func newID() *id {
|
||||
uu := guuid.New()
|
||||
u := [64]byte{}
|
||||
copy(u[:], uu[:])
|
||||
return &id{u: u}
|
||||
}
|
||||
|
||||
// next returns the next ID. This is not thread-safe.
|
||||
func (id *id) next() string {
|
||||
defer func() { id.num++ }()
|
||||
|
||||
binary.BigEndian.PutUint32((id.u[len(guuid.UUID{}):]), id.num)
|
||||
str := base64.StdEncoding.EncodeToString(id.u[:])
|
||||
id.all = append(id.all, str)
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
// issued returns all ids that have been issued. This returned value shares the internal slice so it is not safe to modify the return.
|
||||
// The value is only valid until the next time next() is called.
|
||||
func (id *id) issued() []string {
|
||||
return id.all
|
||||
}
|
|
@ -0,0 +1,273 @@
|
|||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
const finalFileName = "final"
|
||||
|
||||
type fakeBlockWriter struct {
|
||||
path string
|
||||
block int32
|
||||
errOnBlock int32
|
||||
}
|
||||
|
||||
func newFakeBlockWriter() *fakeBlockWriter {
|
||||
f := &fakeBlockWriter{
|
||||
path: filepath.Join(os.TempDir(), newUUID().String()),
|
||||
block: -1,
|
||||
errOnBlock: -1,
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(f.path, 0700); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *fakeBlockWriter) StageBlock(ctx context.Context, blockID string, r io.ReadSeeker, cond LeaseAccessConditions, md5 []byte) (*BlockBlobStageBlockResponse, error) {
|
||||
n := atomic.AddInt32(&f.block, 1)
|
||||
if n == f.errOnBlock {
|
||||
return nil, io.ErrNoProgress
|
||||
}
|
||||
|
||||
blockID = strings.Replace(blockID, "/", "slash", -1)
|
||||
|
||||
fp, err := os.OpenFile(filepath.Join(f.path, blockID), os.O_CREATE+os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not create a stage block file: %s", err)
|
||||
}
|
||||
defer fp.Close()
|
||||
|
||||
if _, err := io.Copy(fp, r); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &BlockBlobStageBlockResponse{}, nil
|
||||
}
|
||||
|
||||
func (f *fakeBlockWriter) CommitBlockList(ctx context.Context, blockIDs []string, headers BlobHTTPHeaders, meta Metadata, access BlobAccessConditions) (*BlockBlobCommitBlockListResponse, error) {
|
||||
dst, err := os.OpenFile(filepath.Join(f.path, finalFileName), os.O_CREATE+os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer dst.Close()
|
||||
|
||||
for _, id := range blockIDs {
|
||||
id = strings.Replace(id, "/", "slash", -1)
|
||||
src, err := os.Open(filepath.Join(f.path, id))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not combine chunk %s: %s", id, err)
|
||||
}
|
||||
_, err = io.Copy(dst, src)
|
||||
src.Close()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("problem writing final file from chunks: %s", err)
|
||||
}
|
||||
}
|
||||
return &BlockBlobCommitBlockListResponse{}, nil
|
||||
}
|
||||
|
||||
func (f *fakeBlockWriter) cleanup() {
|
||||
os.RemoveAll(f.path)
|
||||
}
|
||||
|
||||
func (f *fakeBlockWriter) final() string {
|
||||
return filepath.Join(f.path, finalFileName)
|
||||
}
|
||||
|
||||
func createSrcFile(size int) (string, error) {
|
||||
p := filepath.Join(os.TempDir(), newUUID().String())
|
||||
fp, err := os.OpenFile(p, os.O_CREATE+os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("could not create source file: %s", err)
|
||||
}
|
||||
defer fp.Close()
|
||||
|
||||
lr := &io.LimitedReader{R: rand.New(rand.NewSource(time.Now().UnixNano())), N: int64(size)}
|
||||
copied, err := io.Copy(fp, lr)
|
||||
switch {
|
||||
case err != nil && err != io.EOF:
|
||||
return "", fmt.Errorf("copying %v: %s", size, err)
|
||||
case copied != int64(size):
|
||||
return "", fmt.Errorf("copying %v: copied %d bytes, expected %d", size, copied, size)
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func fileMD5(p string) string {
|
||||
f, err := os.Open(p)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
h := md5.New()
|
||||
if _, err := io.Copy(h, f); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
}
|
||||
|
||||
func TestGetErr(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
canceled, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
err := errors.New("error")
|
||||
|
||||
tests := []struct {
|
||||
desc string
|
||||
ctx context.Context
|
||||
err error
|
||||
want error
|
||||
}{
|
||||
{"No errors", context.Background(), nil, nil},
|
||||
{"Context was cancelled", canceled, nil, context.Canceled},
|
||||
{"Context was cancelled but had error", canceled, err, err},
|
||||
{"Err returned", context.Background(), err, err},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
c := copier{errCh: make(chan error, 1), ctx: test.ctx}
|
||||
if test.err != nil {
|
||||
c.errCh <- test.err
|
||||
}
|
||||
|
||||
got := c.getErr()
|
||||
if test.want != got {
|
||||
t.Errorf("TestGetErr(%s): got %v, want %v", test.desc, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCopyFromReader(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
canceled, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
|
||||
tests := []struct {
|
||||
desc string
|
||||
ctx context.Context
|
||||
o UploadStreamToBlockBlobOptions
|
||||
fileSize int
|
||||
uploadErr bool
|
||||
err bool
|
||||
}{
|
||||
{
|
||||
desc: "context was cancelled",
|
||||
ctx: canceled,
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
desc: "Send file(0 KiB) with default UploadStreamToBlockBlobOptions",
|
||||
ctx: context.Background(),
|
||||
fileSize: 0,
|
||||
},
|
||||
{
|
||||
desc: "Send file(10 KiB) with default UploadStreamToBlockBlobOptions",
|
||||
ctx: context.Background(),
|
||||
fileSize: 10 * 1024,
|
||||
},
|
||||
{
|
||||
desc: "Send file(10 KiB) with default UploadStreamToBlockBlobOptions set to azcopy settings",
|
||||
ctx: context.Background(),
|
||||
fileSize: 10 * 1024,
|
||||
o: UploadStreamToBlockBlobOptions{MaxBuffers: 5, BufferSize: 8 * 1024 * 1024},
|
||||
},
|
||||
{
|
||||
desc: "Send file(1 MiB) with default UploadStreamToBlockBlobOptions",
|
||||
ctx: context.Background(),
|
||||
fileSize: _1MiB,
|
||||
},
|
||||
{
|
||||
desc: "Send file(1 MiB) with default UploadStreamToBlockBlobOptions set to azcopy settings",
|
||||
ctx: context.Background(),
|
||||
fileSize: _1MiB,
|
||||
o: UploadStreamToBlockBlobOptions{MaxBuffers: 5, BufferSize: 8 * 1024 * 1024},
|
||||
},
|
||||
{
|
||||
desc: "Send file(1.5 MiB) with default UploadStreamToBlockBlobOptions",
|
||||
ctx: context.Background(),
|
||||
fileSize: _1MiB + 500*1024,
|
||||
},
|
||||
{
|
||||
desc: "Send file(1.5 MiB) with 2 writers",
|
||||
ctx: context.Background(),
|
||||
fileSize: _1MiB + 500*1024 + 1,
|
||||
o: UploadStreamToBlockBlobOptions{MaxBuffers: 2},
|
||||
},
|
||||
{
|
||||
desc: "Send file(12 MiB) with 3 writers and 1 MiB buffer and a write error",
|
||||
ctx: context.Background(),
|
||||
fileSize: 12 * _1MiB,
|
||||
o: UploadStreamToBlockBlobOptions{MaxBuffers: 2, BufferSize: _1MiB},
|
||||
uploadErr: true,
|
||||
err: true,
|
||||
},
|
||||
{
|
||||
desc: "Send file(12 MiB) with 3 writers and 1.5 MiB buffer",
|
||||
ctx: context.Background(),
|
||||
fileSize: 12 * _1MiB,
|
||||
o: UploadStreamToBlockBlobOptions{MaxBuffers: 2, BufferSize: _1MiB + .5*_1MiB},
|
||||
},
|
||||
{
|
||||
desc: "Send file(12 MiB) with default UploadStreamToBlockBlobOptions set to azcopy settings",
|
||||
ctx: context.Background(),
|
||||
fileSize: 12 * _1MiB,
|
||||
o: UploadStreamToBlockBlobOptions{MaxBuffers: 5, BufferSize: 8 * 1024 * 1024},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
p, err := createSrcFile(test.fileSize)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer os.Remove(p)
|
||||
|
||||
from, err := os.Open(p)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
br := newFakeBlockWriter()
|
||||
defer br.cleanup()
|
||||
if test.uploadErr {
|
||||
br.errOnBlock = 1
|
||||
}
|
||||
|
||||
_, err = copyFromReader(test.ctx, from, br, test.o)
|
||||
switch {
|
||||
case err == nil && test.err:
|
||||
t.Errorf("TestCopyFromReader(%s): got err == nil, want err != nil", test.desc)
|
||||
continue
|
||||
case err != nil && !test.err:
|
||||
t.Errorf("TestCopyFromReader(%s): got err == %s, want err == nil", test.desc, err)
|
||||
continue
|
||||
case err != nil:
|
||||
continue
|
||||
}
|
||||
|
||||
want := fileMD5(p)
|
||||
got := fileMD5(br.final())
|
||||
|
||||
if got != want {
|
||||
t.Errorf("TestCopyFromReader(%s): MD5 not the same: got %s, want %s", test.desc, got, want)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -352,192 +352,44 @@ func DoBatchTransfer(ctx context.Context, o BatchTransferOptions) error {
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const _1MiB = 1024 * 1024
|
||||
|
||||
type UploadStreamToBlockBlobOptions struct {
|
||||
BufferSize int
|
||||
// BufferSize sizes the buffer used to read data from source. If < 1 MiB, defaults to 1 MiB.
|
||||
BufferSize int
|
||||
// MaxBuffers defines the number of simultaneous uploads will be performed to upload the file.
|
||||
MaxBuffers int
|
||||
BlobHTTPHeaders BlobHTTPHeaders
|
||||
Metadata Metadata
|
||||
AccessConditions BlobAccessConditions
|
||||
}
|
||||
|
||||
func (u *UploadStreamToBlockBlobOptions) defaults() {
|
||||
if u.MaxBuffers == 0 {
|
||||
u.MaxBuffers = 1
|
||||
}
|
||||
|
||||
if u.BufferSize < _1MiB {
|
||||
u.BufferSize = _1MiB
|
||||
}
|
||||
}
|
||||
|
||||
// UploadStreamToBlockBlob copies the file held in io.Reader to the Blob at blockBlobURL.
|
||||
// A Context deadline or cancellation will cause this to error.
|
||||
func UploadStreamToBlockBlob(ctx context.Context, reader io.Reader, blockBlobURL BlockBlobURL,
|
||||
o UploadStreamToBlockBlobOptions) (CommonResponse, error) {
|
||||
result, err := uploadStream(ctx, reader,
|
||||
UploadStreamOptions{BufferSize: o.BufferSize, MaxBuffers: o.MaxBuffers},
|
||||
&uploadStreamToBlockBlobOptions{b: blockBlobURL, o: o, blockIDPrefix: newUUID()})
|
||||
o.defaults()
|
||||
|
||||
result, err := copyFromReader(ctx, reader, blockBlobURL, o)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result.(CommonResponse), nil
|
||||
}
|
||||
|
||||
type uploadStreamToBlockBlobOptions struct {
|
||||
b BlockBlobURL
|
||||
o UploadStreamToBlockBlobOptions
|
||||
blockIDPrefix uuid // UUID used with all blockIDs
|
||||
maxBlockNum uint32 // defaults to 0
|
||||
firstBlock []byte // Used only if maxBlockNum is 0
|
||||
}
|
||||
|
||||
func (t *uploadStreamToBlockBlobOptions) start(ctx context.Context) (interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (t *uploadStreamToBlockBlobOptions) chunk(ctx context.Context, num uint32, buffer []byte) error {
|
||||
if num == 0 {
|
||||
t.firstBlock = buffer
|
||||
|
||||
// If whole payload fits in 1 block, don't stage it; End will upload it with 1 I/O operation
|
||||
// If the payload is exactly the same size as the buffer, there may be more content coming in.
|
||||
if len(buffer) < t.o.BufferSize {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// Else, upload a staged block...
|
||||
atomicMorphUint32(&t.maxBlockNum, func(startVal uint32) (val uint32, morphResult interface{}) {
|
||||
// Atomically remember (in t.numBlocks) the maximum block num we've ever seen
|
||||
if startVal < num {
|
||||
return num, nil
|
||||
}
|
||||
return startVal, nil
|
||||
})
|
||||
blockID := newUuidBlockID(t.blockIDPrefix).WithBlockNumber(num).ToBase64()
|
||||
_, err := t.b.StageBlock(ctx, blockID, bytes.NewReader(buffer), LeaseAccessConditions{}, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *uploadStreamToBlockBlobOptions) end(ctx context.Context) (interface{}, error) {
|
||||
// If the first block had the exact same size as the buffer
|
||||
// we would have staged it as a block thinking that there might be more data coming
|
||||
if t.maxBlockNum == 0 && len(t.firstBlock) != t.o.BufferSize {
|
||||
// If whole payload fits in 1 block (block #0), upload it with 1 I/O operation
|
||||
return t.b.Upload(ctx, bytes.NewReader(t.firstBlock),
|
||||
t.o.BlobHTTPHeaders, t.o.Metadata, t.o.AccessConditions)
|
||||
}
|
||||
// Multiple blocks staged, commit them all now
|
||||
blockID := newUuidBlockID(t.blockIDPrefix)
|
||||
blockIDs := make([]string, t.maxBlockNum+1)
|
||||
for bn := uint32(0); bn <= t.maxBlockNum; bn++ {
|
||||
blockIDs[bn] = blockID.WithBlockNumber(bn).ToBase64()
|
||||
}
|
||||
return t.b.CommitBlockList(ctx, blockIDs, t.o.BlobHTTPHeaders, t.o.Metadata, t.o.AccessConditions)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
type iTransfer interface {
|
||||
start(ctx context.Context) (interface{}, error)
|
||||
chunk(ctx context.Context, num uint32, buffer []byte) error
|
||||
end(ctx context.Context) (interface{}, error)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// UploadStreamOptions (defunct) was used internally. This will be removed or made private in a future version.
|
||||
type UploadStreamOptions struct {
|
||||
MaxBuffers int
|
||||
BufferSize int
|
||||
}
|
||||
|
||||
type firstErr struct {
|
||||
lock sync.Mutex
|
||||
finalError error
|
||||
}
|
||||
|
||||
func (fe *firstErr) set(err error) {
|
||||
fe.lock.Lock()
|
||||
if fe.finalError == nil {
|
||||
fe.finalError = err
|
||||
}
|
||||
fe.lock.Unlock()
|
||||
}
|
||||
|
||||
func (fe *firstErr) get() (err error) {
|
||||
fe.lock.Lock()
|
||||
err = fe.finalError
|
||||
fe.lock.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
func uploadStream(ctx context.Context, reader io.Reader, o UploadStreamOptions, t iTransfer) (interface{}, error) {
|
||||
firstErr := firstErr{}
|
||||
ctx, cancel := context.WithCancel(ctx) // New context so that any failure cancels everything
|
||||
defer cancel()
|
||||
wg := sync.WaitGroup{} // Used to know when all outgoing messages have finished processing
|
||||
type OutgoingMsg struct {
|
||||
chunkNum uint32
|
||||
buffer []byte
|
||||
}
|
||||
|
||||
// Create a channel to hold the buffers usable for incoming datsa
|
||||
incoming := make(chan []byte, o.MaxBuffers)
|
||||
outgoing := make(chan OutgoingMsg, o.MaxBuffers) // Channel holding outgoing buffers
|
||||
if result, err := t.start(ctx); err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
numBuffers := 0 // The number of buffers & out going goroutines created so far
|
||||
injectBuffer := func() {
|
||||
// For each Buffer, create it and a goroutine to upload it
|
||||
incoming <- make([]byte, o.BufferSize) // Add the new buffer to the incoming channel so this goroutine can from the reader into it
|
||||
numBuffers++
|
||||
go func() {
|
||||
for outgoingMsg := range outgoing {
|
||||
// Upload the outgoing buffer
|
||||
err := t.chunk(ctx, outgoingMsg.chunkNum, outgoingMsg.buffer)
|
||||
wg.Done() // Indicate this buffer was sent
|
||||
if nil != err {
|
||||
// NOTE: finalErr could be assigned to multiple times here which is OK,
|
||||
// some error will be returned.
|
||||
firstErr.set(err)
|
||||
cancel()
|
||||
}
|
||||
incoming <- outgoingMsg.buffer // The goroutine reading from the stream can reuse this buffer now
|
||||
}
|
||||
}()
|
||||
}
|
||||
injectBuffer() // Create our 1st buffer & outgoing goroutine
|
||||
|
||||
// This goroutine grabs a buffer, reads from the stream into the buffer,
|
||||
// and inserts the buffer into the outgoing channel to be uploaded
|
||||
for c := uint32(0); true; c++ { // Iterate once per chunk
|
||||
var buffer []byte
|
||||
if numBuffers < o.MaxBuffers {
|
||||
select {
|
||||
// We're not at max buffers, see if a previously-created buffer is available
|
||||
case buffer = <-incoming:
|
||||
break
|
||||
default:
|
||||
// No buffer available; inject a new buffer & go routine to process it
|
||||
injectBuffer()
|
||||
buffer = <-incoming // Grab the just-injected buffer
|
||||
}
|
||||
} else {
|
||||
// We are at max buffers, block until we get to reuse one
|
||||
buffer = <-incoming
|
||||
}
|
||||
n, err := io.ReadFull(reader, buffer)
|
||||
if err != nil { // Less than len(buffer) bytes were read
|
||||
buffer = buffer[:n] // Make slice match the # of read bytes
|
||||
}
|
||||
if len(buffer) > 0 {
|
||||
// Buffer not empty, upload it
|
||||
wg.Add(1) // We're posting a buffer to be sent
|
||||
outgoing <- OutgoingMsg{chunkNum: c, buffer: buffer}
|
||||
}
|
||||
if err != nil { // The reader is done, no more outgoing buffers
|
||||
if err == io.EOF || err == io.ErrUnexpectedEOF {
|
||||
err = nil // This function does NOT return an error if io.ReadFull returns io.EOF or io.ErrUnexpectedEOF
|
||||
} else {
|
||||
firstErr.set(err)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
// NOTE: Don't close the incoming channel because the outgoing goroutines post buffers into it when they are done
|
||||
close(outgoing) // Make all the outgoing goroutines terminate when this channel is empty
|
||||
wg.Wait() // Wait for all pending outgoing messages to complete
|
||||
err := firstErr.get()
|
||||
if err == nil {
|
||||
// If no error, after all blocks uploaded, commit them to the blob & return the result
|
||||
return t.end(ctx)
|
||||
}
|
||||
return nil, err
|
||||
MaxBuffers int
|
||||
}
|
||||
|
|
|
@ -5,9 +5,6 @@ import (
|
|||
"io"
|
||||
"net/url"
|
||||
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
)
|
||||
|
||||
|
@ -135,56 +132,3 @@ func (bb BlockBlobURL) CopyFromURL(ctx context.Context, source url.URL, metadata
|
|||
dstIfMatchETag, dstIfNoneMatchETag,
|
||||
dstLeaseID, nil, srcContentMD5)
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
type BlockID [64]byte
|
||||
|
||||
func (blockID BlockID) ToBase64() string {
|
||||
return base64.StdEncoding.EncodeToString(blockID[:])
|
||||
}
|
||||
|
||||
func (blockID *BlockID) FromBase64(s string) error {
|
||||
*blockID = BlockID{} // Zero out the block ID
|
||||
_, err := base64.StdEncoding.Decode(blockID[:], ([]byte)(s))
|
||||
return err
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
type uuidBlockID BlockID
|
||||
|
||||
func (ubi uuidBlockID) UUID() uuid {
|
||||
u := uuid{}
|
||||
copy(u[:], ubi[:len(u)])
|
||||
return u
|
||||
}
|
||||
|
||||
func (ubi uuidBlockID) Number() uint32 {
|
||||
return binary.BigEndian.Uint32(ubi[len(uuid{}):])
|
||||
}
|
||||
|
||||
func newUuidBlockID(u uuid) uuidBlockID {
|
||||
ubi := uuidBlockID{} // Create a new uuidBlockID
|
||||
copy(ubi[:len(u)], u[:]) // Copy the specified UUID into it
|
||||
// Block number defaults to 0
|
||||
return ubi
|
||||
}
|
||||
|
||||
func (ubi *uuidBlockID) SetUUID(u uuid) *uuidBlockID {
|
||||
copy(ubi[:len(u)], u[:])
|
||||
return ubi
|
||||
}
|
||||
|
||||
func (ubi uuidBlockID) WithBlockNumber(blockNumber uint32) uuidBlockID {
|
||||
binary.BigEndian.PutUint32(ubi[len(uuid{}):], blockNumber) // Put block number after UUID
|
||||
return ubi // Return the passed-in copy
|
||||
}
|
||||
|
||||
func (ubi uuidBlockID) ToBase64() string {
|
||||
return BlockID(ubi).ToBase64()
|
||||
}
|
||||
|
||||
func (ubi *uuidBlockID) FromBase64(s string) error {
|
||||
return (*BlockID)(ubi).FromBase64(s)
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,4 +1,4 @@
|
|||
package azblob_test
|
||||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -8,7 +8,6 @@ import (
|
|||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-storage-blob-go/azblob"
|
||||
chk "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
|
@ -35,15 +34,15 @@ func performUploadStreamToBlockBlobTest(c *chk.C, blobSize, bufferSize, maxBuffe
|
|||
blobContentReader, blobData := getRandomDataAndReader(blobSize)
|
||||
|
||||
// Perform UploadStreamToBlockBlob
|
||||
uploadResp, err := azblob.UploadStreamToBlockBlob(ctx, blobContentReader, blobURL,
|
||||
azblob.UploadStreamToBlockBlobOptions{BufferSize: bufferSize, MaxBuffers: maxBuffers})
|
||||
uploadResp, err := UploadStreamToBlockBlob(ctx, blobContentReader, blobURL,
|
||||
UploadStreamToBlockBlobOptions{BufferSize: bufferSize, MaxBuffers: maxBuffers})
|
||||
|
||||
// Assert that upload was successful
|
||||
c.Assert(err, chk.Equals, nil)
|
||||
c.Assert(uploadResp.Response().StatusCode, chk.Equals, 201)
|
||||
|
||||
// Download the blob to verify
|
||||
downloadResponse, err := blobURL.Download(ctx, 0, 0, azblob.BlobAccessConditions{}, false)
|
||||
downloadResponse, err := blobURL.Download(ctx, 0, 0, BlobAccessConditions{}, false)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
// Assert that the content is correct
|
||||
|
@ -108,8 +107,8 @@ func performUploadAndDownloadFileTest(c *chk.C, fileSize, blockSize, parallelism
|
|||
blockBlobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
// Upload the file to a block blob
|
||||
response, err := azblob.UploadFileToBlockBlob(context.Background(), file, blockBlobURL,
|
||||
azblob.UploadToBlockBlobOptions{
|
||||
response, err := UploadFileToBlockBlob(context.Background(), file, blockBlobURL,
|
||||
UploadToBlockBlobOptions{
|
||||
BlockSize: int64(blockSize),
|
||||
Parallelism: uint16(parallelism),
|
||||
// If Progress is non-nil, this function is called periodically as bytes are uploaded.
|
||||
|
@ -128,9 +127,9 @@ func performUploadAndDownloadFileTest(c *chk.C, fileSize, blockSize, parallelism
|
|||
defer os.Remove(destFileName)
|
||||
|
||||
// Perform download
|
||||
err = azblob.DownloadBlobToFile(context.Background(), blockBlobURL.BlobURL, int64(downloadOffset), int64(downloadCount),
|
||||
err = DownloadBlobToFile(context.Background(), blockBlobURL.BlobURL, int64(downloadOffset), int64(downloadCount),
|
||||
destFile,
|
||||
azblob.DownloadFromBlobOptions{
|
||||
DownloadFromBlobOptions{
|
||||
BlockSize: int64(blockSize),
|
||||
Parallelism: uint16(parallelism),
|
||||
// If Progress is non-nil, this function is called periodically as bytes are uploaded.
|
||||
|
@ -143,7 +142,7 @@ func performUploadAndDownloadFileTest(c *chk.C, fileSize, blockSize, parallelism
|
|||
|
||||
// Assert downloaded data is consistent
|
||||
var destBuffer []byte
|
||||
if downloadCount == azblob.CountToEnd {
|
||||
if downloadCount == CountToEnd {
|
||||
destBuffer = make([]byte, fileSize-downloadOffset)
|
||||
} else {
|
||||
destBuffer = make([]byte, downloadCount)
|
||||
|
@ -233,8 +232,8 @@ func performUploadAndDownloadBufferTest(c *chk.C, blobSize, blockSize, paralleli
|
|||
blockBlobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
// Pass the Context, stream, stream size, block blob URL, and options to StreamToBlockBlob
|
||||
response, err := azblob.UploadBufferToBlockBlob(context.Background(), bytesToUpload, blockBlobURL,
|
||||
azblob.UploadToBlockBlobOptions{
|
||||
response, err := UploadBufferToBlockBlob(context.Background(), bytesToUpload, blockBlobURL,
|
||||
UploadToBlockBlobOptions{
|
||||
BlockSize: int64(blockSize),
|
||||
Parallelism: uint16(parallelism),
|
||||
// If Progress is non-nil, this function is called periodically as bytes are uploaded.
|
||||
|
@ -247,16 +246,16 @@ func performUploadAndDownloadBufferTest(c *chk.C, blobSize, blockSize, paralleli
|
|||
|
||||
// Set up buffer to download the blob to
|
||||
var destBuffer []byte
|
||||
if downloadCount == azblob.CountToEnd {
|
||||
if downloadCount == CountToEnd {
|
||||
destBuffer = make([]byte, blobSize-downloadOffset)
|
||||
} else {
|
||||
destBuffer = make([]byte, downloadCount)
|
||||
}
|
||||
|
||||
// Download the blob to a buffer
|
||||
err = azblob.DownloadBlobToBuffer(context.Background(), blockBlobURL.BlobURL, int64(downloadOffset), int64(downloadCount),
|
||||
destBuffer, azblob.DownloadFromBlobOptions{
|
||||
AccessConditions: azblob.BlobAccessConditions{},
|
||||
err = DownloadBlobToBuffer(context.Background(), blockBlobURL.BlobURL, int64(downloadOffset), int64(downloadCount),
|
||||
destBuffer, DownloadFromBlobOptions{
|
||||
AccessConditions: BlobAccessConditions{},
|
||||
BlockSize: int64(blockSize),
|
||||
Parallelism: uint16(parallelism),
|
||||
// If Progress is non-nil, this function is called periodically as bytes are uploaded.
|
||||
|
@ -358,7 +357,7 @@ func (s *aztestsSuite) TestBasicDoBatchTransfer(c *chk.C) {
|
|||
totalSizeCount := int64(0)
|
||||
runCount := int64(0)
|
||||
|
||||
err := azblob.DoBatchTransfer(ctx, azblob.BatchTransferOptions{
|
||||
err := DoBatchTransfer(ctx, BatchTransferOptions{
|
||||
TransferSize: test.transferSize,
|
||||
ChunkSize: test.chunkSize,
|
||||
Parallelism: test.parallelism,
|
||||
|
@ -399,7 +398,7 @@ func (s *aztestsSuite) TestDoBatchTransferWithError(c *chk.C) {
|
|||
mmf := mockMMF{failHandle: c}
|
||||
expectedFirstError := errors.New("#3 means trouble")
|
||||
|
||||
err := azblob.DoBatchTransfer(ctx, azblob.BatchTransferOptions{
|
||||
err := DoBatchTransfer(ctx, BatchTransferOptions{
|
||||
TransferSize: 5,
|
||||
ChunkSize: 1,
|
||||
Parallelism: 5,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package azblob_test
|
||||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -12,7 +12,6 @@ import (
|
|||
chk "gopkg.in/check.v1"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
"github.com/Azure/azure-storage-blob-go/azblob"
|
||||
)
|
||||
|
||||
// For testing docs, see: https://labix.org/gocheck
|
||||
|
@ -147,8 +146,8 @@ func (p *retryTestPolicy) Do(ctx context.Context, request pipeline.Request) (res
|
|||
|
||||
func testRetryTestScenario(c *chk.C, scenario retryTestScenario) {
|
||||
u, _ := url.Parse("http://PrimaryDC")
|
||||
retryOptions := azblob.RetryOptions{
|
||||
Policy: azblob.RetryPolicyExponential,
|
||||
retryOptions := RetryOptions{
|
||||
Policy: RetryPolicyExponential,
|
||||
MaxTries: 6,
|
||||
TryTimeout: 2 * time.Second,
|
||||
RetryDelay: 1 * time.Second,
|
||||
|
@ -160,7 +159,7 @@ func testRetryTestScenario(c *chk.C, scenario retryTestScenario) {
|
|||
ctx, cancel := context.WithTimeout(ctx, 64 /*2^MaxTries(6)*/ *retryOptions.TryTimeout)
|
||||
retrytestPolicyFactory := newRetryTestPolicyFactory(c, scenario, retryOptions.MaxTries, cancel)
|
||||
factories := [...]pipeline.Factory{
|
||||
azblob.NewRetryPolicyFactory(retryOptions),
|
||||
NewRetryPolicyFactory(retryOptions),
|
||||
retrytestPolicyFactory,
|
||||
}
|
||||
p := pipeline.NewPipeline(factories[:], pipeline.Options{})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package azblob_test
|
||||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -10,7 +10,6 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-storage-blob-go/azblob"
|
||||
chk "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
|
@ -68,7 +67,7 @@ func (r *perByteReader) Read(b []byte) (n int, err error) {
|
|||
// error
|
||||
select {
|
||||
case <-r.closeChannel:
|
||||
return n, errors.New(azblob.ReadOnClosedBodyMessage)
|
||||
return n, errors.New(ReadOnClosedBodyMessage)
|
||||
case <-time.After(r.sleepDuration):
|
||||
return n, nil
|
||||
}
|
||||
|
@ -114,7 +113,7 @@ func (s *aztestsSuite) TestRetryReaderReadWithRetry(c *chk.C) {
|
|||
body.doInjectTimes = 1
|
||||
body.injectedError = &net.DNSError{IsTemporary: true}
|
||||
|
||||
getter := func(ctx context.Context, info azblob.HTTPGetterInfo) (*http.Response, error) {
|
||||
getter := func(ctx context.Context, info HTTPGetterInfo) (*http.Response, error) {
|
||||
r := http.Response{}
|
||||
body.currentByteIndex = int(info.Offset)
|
||||
r.Body = body
|
||||
|
@ -122,15 +121,15 @@ func (s *aztestsSuite) TestRetryReaderReadWithRetry(c *chk.C) {
|
|||
return &r, nil
|
||||
}
|
||||
|
||||
httpGetterInfo := azblob.HTTPGetterInfo{Offset: 0, Count: int64(byteCount)}
|
||||
httpGetterInfo := HTTPGetterInfo{Offset: 0, Count: int64(byteCount)}
|
||||
initResponse, err := getter(context.Background(), httpGetterInfo)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
rrOptions := azblob.RetryReaderOptions{MaxRetryRequests: 1}
|
||||
rrOptions := RetryReaderOptions{MaxRetryRequests: 1}
|
||||
if logThisRun {
|
||||
rrOptions.NotifyFailedRead = failureMethod
|
||||
}
|
||||
retryReader := azblob.NewRetryReader(context.Background(), initResponse, httpGetterInfo, rrOptions, getter)
|
||||
retryReader := NewRetryReader(context.Background(), initResponse, httpGetterInfo, rrOptions, getter)
|
||||
|
||||
// should fail and succeed through retry
|
||||
can := make([]byte, 1)
|
||||
|
@ -181,7 +180,7 @@ func (s *aztestsSuite) TestRetryReaderReadNegativeNormalFail(c *chk.C) {
|
|||
startResponse := http.Response{}
|
||||
startResponse.Body = body
|
||||
|
||||
getter := func(ctx context.Context, info azblob.HTTPGetterInfo) (*http.Response, error) {
|
||||
getter := func(ctx context.Context, info HTTPGetterInfo) (*http.Response, error) {
|
||||
r := http.Response{}
|
||||
body.currentByteIndex = int(info.Offset)
|
||||
r.Body = body
|
||||
|
@ -189,10 +188,10 @@ func (s *aztestsSuite) TestRetryReaderReadNegativeNormalFail(c *chk.C) {
|
|||
return &r, nil
|
||||
}
|
||||
|
||||
rrOptions := azblob.RetryReaderOptions{
|
||||
rrOptions := RetryReaderOptions{
|
||||
MaxRetryRequests: 1,
|
||||
NotifyFailedRead: failureMethod}
|
||||
retryReader := azblob.NewRetryReader(context.Background(), &startResponse, azblob.HTTPGetterInfo{Offset: 0, Count: int64(byteCount)}, rrOptions, getter)
|
||||
retryReader := NewRetryReader(context.Background(), &startResponse, HTTPGetterInfo{Offset: 0, Count: int64(byteCount)}, rrOptions, getter)
|
||||
|
||||
// should fail
|
||||
can := make([]byte, 1)
|
||||
|
@ -221,7 +220,7 @@ func (s *aztestsSuite) TestRetryReaderReadCount0(c *chk.C) {
|
|||
startResponse := http.Response{}
|
||||
startResponse.Body = body
|
||||
|
||||
getter := func(ctx context.Context, info azblob.HTTPGetterInfo) (*http.Response, error) {
|
||||
getter := func(ctx context.Context, info HTTPGetterInfo) (*http.Response, error) {
|
||||
r := http.Response{}
|
||||
body.currentByteIndex = int(info.Offset)
|
||||
r.Body = body
|
||||
|
@ -229,7 +228,7 @@ func (s *aztestsSuite) TestRetryReaderReadCount0(c *chk.C) {
|
|||
return &r, nil
|
||||
}
|
||||
|
||||
retryReader := azblob.NewRetryReader(context.Background(), &startResponse, azblob.HTTPGetterInfo{Offset: 0, Count: int64(byteCount)}, azblob.RetryReaderOptions{MaxRetryRequests: 1}, getter)
|
||||
retryReader := NewRetryReader(context.Background(), &startResponse, HTTPGetterInfo{Offset: 0, Count: int64(byteCount)}, RetryReaderOptions{MaxRetryRequests: 1}, getter)
|
||||
|
||||
// should consume the only byte
|
||||
can := make([]byte, 1)
|
||||
|
@ -254,7 +253,7 @@ func (s *aztestsSuite) TestRetryReaderReadNegativeNonRetriableError(c *chk.C) {
|
|||
startResponse := http.Response{}
|
||||
startResponse.Body = body
|
||||
|
||||
getter := func(ctx context.Context, info azblob.HTTPGetterInfo) (*http.Response, error) {
|
||||
getter := func(ctx context.Context, info HTTPGetterInfo) (*http.Response, error) {
|
||||
r := http.Response{}
|
||||
body.currentByteIndex = int(info.Offset)
|
||||
r.Body = body
|
||||
|
@ -262,7 +261,7 @@ func (s *aztestsSuite) TestRetryReaderReadNegativeNonRetriableError(c *chk.C) {
|
|||
return &r, nil
|
||||
}
|
||||
|
||||
retryReader := azblob.NewRetryReader(context.Background(), &startResponse, azblob.HTTPGetterInfo{Offset: 0, Count: int64(byteCount)}, azblob.RetryReaderOptions{MaxRetryRequests: 2}, getter)
|
||||
retryReader := NewRetryReader(context.Background(), &startResponse, HTTPGetterInfo{Offset: 0, Count: int64(byteCount)}, RetryReaderOptions{MaxRetryRequests: 2}, getter)
|
||||
|
||||
dest := make([]byte, 1)
|
||||
_, err := retryReader.Read(dest)
|
||||
|
@ -289,7 +288,7 @@ func (s *aztestsSuite) TestRetryReaderReadWithForcedRetry(c *chk.C) {
|
|||
sleepDuration := 100 * time.Millisecond
|
||||
randBytes := make([]byte, byteCount)
|
||||
_, _ = rand.Read(randBytes)
|
||||
getter := func(ctx context.Context, info azblob.HTTPGetterInfo) (*http.Response, error) {
|
||||
getter := func(ctx context.Context, info HTTPGetterInfo) (*http.Response, error) {
|
||||
body := newSingleUsePerByteReader(randBytes) // make new one every time, since we force closes in this test, and its unusable after a close
|
||||
body.sleepDuration = sleepDuration
|
||||
r := http.Response{}
|
||||
|
@ -299,13 +298,13 @@ func (s *aztestsSuite) TestRetryReaderReadWithForcedRetry(c *chk.C) {
|
|||
return &r, nil
|
||||
}
|
||||
|
||||
httpGetterInfo := azblob.HTTPGetterInfo{Offset: 0, Count: int64(byteCount)}
|
||||
httpGetterInfo := HTTPGetterInfo{Offset: 0, Count: int64(byteCount)}
|
||||
initResponse, err := getter(context.Background(), httpGetterInfo)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
rrOptions := azblob.RetryReaderOptions{MaxRetryRequests: 2, TreatEarlyCloseAsError: !enableRetryOnEarlyClose}
|
||||
rrOptions := RetryReaderOptions{MaxRetryRequests: 2, TreatEarlyCloseAsError: !enableRetryOnEarlyClose}
|
||||
rrOptions.NotifyFailedRead = failureMethod
|
||||
retryReader := azblob.NewRetryReader(context.Background(), initResponse, httpGetterInfo, rrOptions, getter)
|
||||
retryReader := NewRetryReader(context.Background(), initResponse, httpGetterInfo, rrOptions, getter)
|
||||
|
||||
// set up timed cancellation from separate goroutine
|
||||
go func() {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package azblob_test
|
||||
package azblob
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/Azure/azure-storage-blob-go/azblob"
|
||||
chk "gopkg.in/check.v1"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
chk "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *aztestsSuite) TestSnapshotSAS(c *chk.C) {
|
||||
|
@ -14,8 +14,8 @@ func (s *aztestsSuite) TestSnapshotSAS(c *chk.C) {
|
|||
containerURL, containerName := getContainerURL(c, bsu)
|
||||
blobURL, blobName := getBlockBlobURL(c, containerURL)
|
||||
|
||||
_, err := containerURL.Create(ctx, azblob.Metadata{}, azblob.PublicAccessNone)
|
||||
defer containerURL.Delete(ctx, azblob.ContainerAccessConditions{})
|
||||
_, err := containerURL.Create(ctx, Metadata{}, PublicAccessNone)
|
||||
defer containerURL.Delete(ctx, ContainerAccessConditions{})
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
@ -24,19 +24,19 @@ func (s *aztestsSuite) TestSnapshotSAS(c *chk.C) {
|
|||
burl := containerURL.NewBlockBlobURL(blobName)
|
||||
data := "Hello world!"
|
||||
|
||||
_, err = burl.Upload(ctx, strings.NewReader(data), azblob.BlobHTTPHeaders{ContentType: "text/plain"}, azblob.Metadata{}, azblob.BlobAccessConditions{})
|
||||
_, err = burl.Upload(ctx, strings.NewReader(data), BlobHTTPHeaders{ContentType: "text/plain"}, Metadata{}, BlobAccessConditions{})
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
//Create a snapshot & URL
|
||||
createSnapshot, err := burl.CreateSnapshot(ctx, azblob.Metadata{}, azblob.BlobAccessConditions{})
|
||||
createSnapshot, err := burl.CreateSnapshot(ctx, Metadata{}, BlobAccessConditions{})
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
//Format snapshot time
|
||||
snapTime, err := time.Parse(azblob.SnapshotTimeFormat, createSnapshot.Snapshot())
|
||||
snapTime, err := time.Parse(SnapshotTimeFormat, createSnapshot.Snapshot())
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
@ -49,40 +49,40 @@ func (s *aztestsSuite) TestSnapshotSAS(c *chk.C) {
|
|||
}
|
||||
|
||||
//Create SAS query
|
||||
snapSASQueryParams, err := azblob.BlobSASSignatureValues{
|
||||
snapSASQueryParams, err := BlobSASSignatureValues{
|
||||
StartTime: currentTime,
|
||||
ExpiryTime: currentTime.Add(48 * time.Hour),
|
||||
SnapshotTime: snapTime,
|
||||
Permissions: "racwd",
|
||||
ContainerName: containerName,
|
||||
BlobName: blobName,
|
||||
Protocol: azblob.SASProtocolHTTPS,
|
||||
Protocol: SASProtocolHTTPS,
|
||||
}.NewSASQueryParameters(credential)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
//Attach SAS query to block blob URL
|
||||
p := azblob.NewPipeline(azblob.NewAnonymousCredential(), azblob.PipelineOptions{})
|
||||
snapParts := azblob.NewBlobURLParts(blobURL.URL())
|
||||
p := NewPipeline(NewAnonymousCredential(), PipelineOptions{})
|
||||
snapParts := NewBlobURLParts(blobURL.URL())
|
||||
snapParts.SAS = snapSASQueryParams
|
||||
sburl := azblob.NewBlockBlobURL(snapParts.URL(), p)
|
||||
sburl := NewBlockBlobURL(snapParts.URL(), p)
|
||||
|
||||
//Test the snapshot
|
||||
downloadResponse, err := sburl.Download(ctx, 0, 0, azblob.BlobAccessConditions{}, false)
|
||||
downloadResponse, err := sburl.Download(ctx, 0, 0, BlobAccessConditions{}, false)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
downloadedData := &bytes.Buffer{}
|
||||
reader := downloadResponse.Body(azblob.RetryReaderOptions{})
|
||||
reader := downloadResponse.Body(RetryReaderOptions{})
|
||||
downloadedData.ReadFrom(reader)
|
||||
reader.Close()
|
||||
|
||||
c.Assert(data, chk.Equals, downloadedData.String())
|
||||
|
||||
//Try to delete snapshot -------------------------------------------------------------------------------------------
|
||||
_, err = sburl.Delete(ctx, azblob.DeleteSnapshotsOptionNone, azblob.BlobAccessConditions{})
|
||||
_, err = sburl.Delete(ctx, DeleteSnapshotsOptionNone, BlobAccessConditions{})
|
||||
if err != nil { //This shouldn't fail.
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
@ -91,16 +91,16 @@ func (s *aztestsSuite) TestSnapshotSAS(c *chk.C) {
|
|||
//If this succeeds, it means a normal SAS token was created.
|
||||
|
||||
fsburl := containerURL.NewBlockBlobURL("failsnap")
|
||||
_, err = fsburl.Upload(ctx, strings.NewReader(data), azblob.BlobHTTPHeaders{ContentType: "text/plain"}, azblob.Metadata{}, azblob.BlobAccessConditions{})
|
||||
_, err = fsburl.Upload(ctx, strings.NewReader(data), BlobHTTPHeaders{ContentType: "text/plain"}, Metadata{}, BlobAccessConditions{})
|
||||
if err != nil {
|
||||
c.Fatal(err) //should succeed to create the blob via normal auth means
|
||||
}
|
||||
|
||||
fsburlparts := azblob.NewBlobURLParts(fsburl.URL())
|
||||
fsburlparts := NewBlobURLParts(fsburl.URL())
|
||||
fsburlparts.SAS = snapSASQueryParams
|
||||
fsburl = azblob.NewBlockBlobURL(fsburlparts.URL(), p) //re-use fsburl as we don't need the sharedkey version anymore
|
||||
fsburl = NewBlockBlobURL(fsburlparts.URL(), p) //re-use fsburl as we don't need the sharedkey version anymore
|
||||
|
||||
resp, err := fsburl.Delete(ctx, azblob.DeleteSnapshotsOptionNone, azblob.BlobAccessConditions{})
|
||||
resp, err := fsburl.Delete(ctx, DeleteSnapshotsOptionNone, BlobAccessConditions{})
|
||||
if err == nil {
|
||||
c.Fatal(resp) //This SHOULD fail. Otherwise we have a normal SAS token...
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package azblob_test
|
||||
package azblob
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
@ -20,7 +20,6 @@ import (
|
|||
"math/rand"
|
||||
|
||||
"github.com/Azure/azure-pipeline-go/pipeline"
|
||||
"github.com/Azure/azure-storage-blob-go/azblob"
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
)
|
||||
|
||||
|
@ -35,7 +34,7 @@ type aztestsSuite struct{}
|
|||
var _ = chk.Suite(&aztestsSuite{})
|
||||
|
||||
func (s *aztestsSuite) TestRetryPolicyRetryReadsFromSecondaryHostField(c *chk.C) {
|
||||
_, found := reflect.TypeOf(azblob.RetryOptions{}).FieldByName("RetryReadsFromSecondaryHost")
|
||||
_, found := reflect.TypeOf(RetryOptions{}).FieldByName("RetryReadsFromSecondaryHost")
|
||||
if !found {
|
||||
// Make sure the RetryOption was not erroneously overwritten
|
||||
c.Fatal("RetryOption's RetryReadsFromSecondaryHost field must exist in the Blob SDK - uncomment it and make sure the field is returned from the retryReadsFromSecondaryHost() method too!")
|
||||
|
@ -51,7 +50,7 @@ const (
|
|||
)
|
||||
|
||||
var ctx = context.Background()
|
||||
var basicHeaders = azblob.BlobHTTPHeaders{
|
||||
var basicHeaders = BlobHTTPHeaders{
|
||||
ContentType: "my_type",
|
||||
ContentDisposition: "my_disposition",
|
||||
CacheControl: "control",
|
||||
|
@ -60,7 +59,7 @@ var basicHeaders = azblob.BlobHTTPHeaders{
|
|||
ContentEncoding: "my_encoding",
|
||||
}
|
||||
|
||||
var basicMetadata = azblob.Metadata{"foo": "bar"}
|
||||
var basicMetadata = Metadata{"foo": "bar"}
|
||||
|
||||
type testPipeline struct{}
|
||||
|
||||
|
@ -104,28 +103,28 @@ func generateBlobName() string {
|
|||
return generateName(blobPrefix)
|
||||
}
|
||||
|
||||
func getContainerURL(c *chk.C, bsu azblob.ServiceURL) (container azblob.ContainerURL, name string) {
|
||||
func getContainerURL(c *chk.C, bsu ServiceURL) (container ContainerURL, name string) {
|
||||
name = generateContainerName()
|
||||
container = bsu.NewContainerURL(name)
|
||||
|
||||
return container, name
|
||||
}
|
||||
|
||||
func getBlockBlobURL(c *chk.C, container azblob.ContainerURL) (blob azblob.BlockBlobURL, name string) {
|
||||
func getBlockBlobURL(c *chk.C, container ContainerURL) (blob BlockBlobURL, name string) {
|
||||
name = generateBlobName()
|
||||
blob = container.NewBlockBlobURL(name)
|
||||
|
||||
return blob, name
|
||||
}
|
||||
|
||||
func getAppendBlobURL(c *chk.C, container azblob.ContainerURL) (blob azblob.AppendBlobURL, name string) {
|
||||
func getAppendBlobURL(c *chk.C, container ContainerURL) (blob AppendBlobURL, name string) {
|
||||
name = generateBlobName()
|
||||
blob = container.NewAppendBlobURL(name)
|
||||
|
||||
return blob, name
|
||||
}
|
||||
|
||||
func getPageBlobURL(c *chk.C, container azblob.ContainerURL) (blob azblob.PageBlobURL, name string) {
|
||||
func getPageBlobURL(c *chk.C, container ContainerURL) (blob PageBlobURL, name string) {
|
||||
name = generateBlobName()
|
||||
blob = container.NewPageBlobURL(name)
|
||||
|
||||
|
@ -143,33 +142,33 @@ func getRandomDataAndReader(n int) (*bytes.Reader, []byte) {
|
|||
return bytes.NewReader(data), data
|
||||
}
|
||||
|
||||
func createNewContainer(c *chk.C, bsu azblob.ServiceURL) (container azblob.ContainerURL, name string) {
|
||||
func createNewContainer(c *chk.C, bsu ServiceURL) (container ContainerURL, name string) {
|
||||
container, name = getContainerURL(c, bsu)
|
||||
|
||||
cResp, err := container.Create(ctx, nil, azblob.PublicAccessNone)
|
||||
cResp, err := container.Create(ctx, nil, PublicAccessNone)
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(cResp.StatusCode(), chk.Equals, 201)
|
||||
return container, name
|
||||
}
|
||||
|
||||
func createNewContainerWithSuffix(c *chk.C, bsu azblob.ServiceURL, suffix string) (container azblob.ContainerURL, name string) {
|
||||
func createNewContainerWithSuffix(c *chk.C, bsu ServiceURL, suffix string) (container ContainerURL, name string) {
|
||||
// The goal of adding the suffix is to be able to predetermine what order the containers will be in when listed.
|
||||
// We still need the container prefix to come first, though, to ensure only containers as a part of this test
|
||||
// are listed at all.
|
||||
name = generateName(containerPrefix + suffix)
|
||||
container = bsu.NewContainerURL(name)
|
||||
|
||||
cResp, err := container.Create(ctx, nil, azblob.PublicAccessNone)
|
||||
cResp, err := container.Create(ctx, nil, PublicAccessNone)
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(cResp.StatusCode(), chk.Equals, 201)
|
||||
return container, name
|
||||
}
|
||||
|
||||
func createNewBlockBlob(c *chk.C, container azblob.ContainerURL) (blob azblob.BlockBlobURL, name string) {
|
||||
func createNewBlockBlob(c *chk.C, container ContainerURL) (blob BlockBlobURL, name string) {
|
||||
blob, name = getBlockBlobURL(c, container)
|
||||
|
||||
cResp, err := blob.Upload(ctx, strings.NewReader(blockBlobDefaultData), azblob.BlobHTTPHeaders{},
|
||||
nil, azblob.BlobAccessConditions{})
|
||||
cResp, err := blob.Upload(ctx, strings.NewReader(blockBlobDefaultData), BlobHTTPHeaders{},
|
||||
nil, BlobAccessConditions{})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(cResp.StatusCode(), chk.Equals, 201)
|
||||
|
@ -177,68 +176,68 @@ func createNewBlockBlob(c *chk.C, container azblob.ContainerURL) (blob azblob.Bl
|
|||
return
|
||||
}
|
||||
|
||||
func createNewAppendBlob(c *chk.C, container azblob.ContainerURL) (blob azblob.AppendBlobURL, name string) {
|
||||
func createNewAppendBlob(c *chk.C, container ContainerURL) (blob AppendBlobURL, name string) {
|
||||
blob, name = getAppendBlobURL(c, container)
|
||||
|
||||
resp, err := blob.Create(ctx, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
resp, err := blob.Create(ctx, BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.StatusCode(), chk.Equals, 201)
|
||||
return
|
||||
}
|
||||
|
||||
func createNewPageBlob(c *chk.C, container azblob.ContainerURL) (blob azblob.PageBlobURL, name string) {
|
||||
func createNewPageBlob(c *chk.C, container ContainerURL) (blob PageBlobURL, name string) {
|
||||
blob, name = getPageBlobURL(c, container)
|
||||
|
||||
resp, err := blob.Create(ctx, azblob.PageBlobPageBytes*10, 0, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
resp, err := blob.Create(ctx, PageBlobPageBytes*10, 0, BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.StatusCode(), chk.Equals, 201)
|
||||
return
|
||||
}
|
||||
|
||||
func createNewPageBlobWithSize(c *chk.C, container azblob.ContainerURL, sizeInBytes int64) (blob azblob.PageBlobURL, name string) {
|
||||
func createNewPageBlobWithSize(c *chk.C, container ContainerURL, sizeInBytes int64) (blob PageBlobURL, name string) {
|
||||
blob, name = getPageBlobURL(c, container)
|
||||
|
||||
resp, err := blob.Create(ctx, sizeInBytes, 0, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
resp, err := blob.Create(ctx, sizeInBytes, 0, BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.StatusCode(), chk.Equals, 201)
|
||||
return
|
||||
}
|
||||
|
||||
func createBlockBlobWithPrefix(c *chk.C, container azblob.ContainerURL, prefix string) (blob azblob.BlockBlobURL, name string) {
|
||||
func createBlockBlobWithPrefix(c *chk.C, container ContainerURL, prefix string) (blob BlockBlobURL, name string) {
|
||||
name = prefix + generateName(blobPrefix)
|
||||
blob = container.NewBlockBlobURL(name)
|
||||
|
||||
cResp, err := blob.Upload(ctx, strings.NewReader(blockBlobDefaultData), azblob.BlobHTTPHeaders{},
|
||||
nil, azblob.BlobAccessConditions{})
|
||||
cResp, err := blob.Upload(ctx, strings.NewReader(blockBlobDefaultData), BlobHTTPHeaders{},
|
||||
nil, BlobAccessConditions{})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(cResp.StatusCode(), chk.Equals, 201)
|
||||
return
|
||||
}
|
||||
|
||||
func deleteContainer(c *chk.C, container azblob.ContainerURL) {
|
||||
resp, err := container.Delete(ctx, azblob.ContainerAccessConditions{})
|
||||
func deleteContainer(c *chk.C, container ContainerURL) {
|
||||
resp, err := container.Delete(ctx, ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.StatusCode(), chk.Equals, 202)
|
||||
}
|
||||
|
||||
func getGenericCredential(accountType string) (*azblob.SharedKeyCredential, error) {
|
||||
func getGenericCredential(accountType string) (*SharedKeyCredential, error) {
|
||||
accountNameEnvVar := accountType + "ACCOUNT_NAME"
|
||||
accountKeyEnvVar := accountType + "ACCOUNT_KEY"
|
||||
accountName, accountKey := os.Getenv(accountNameEnvVar), os.Getenv(accountKeyEnvVar)
|
||||
if accountName == "" || accountKey == "" {
|
||||
return nil, errors.New(accountNameEnvVar + " and/or " + accountKeyEnvVar + " environment variables not specified.")
|
||||
}
|
||||
return azblob.NewSharedKeyCredential(accountName, accountKey)
|
||||
return NewSharedKeyCredential(accountName, accountKey)
|
||||
}
|
||||
|
||||
//getOAuthCredential can intake a OAuth credential from environment variables in one of the following ways:
|
||||
//Direct: Supply a ADAL OAuth token in OAUTH_TOKEN and application ID in APPLICATION_ID to refresh the supplied token.
|
||||
//Client secret: Supply a client secret in CLIENT_SECRET and application ID in APPLICATION_ID for SPN auth.
|
||||
//TENANT_ID is optional and will be inferred as common if it is not explicitly defined.
|
||||
func getOAuthCredential(accountType string) (*azblob.TokenCredential, error) {
|
||||
func getOAuthCredential(accountType string) (*TokenCredential, error) {
|
||||
oauthTokenEnvVar := accountType + "OAUTH_TOKEN"
|
||||
clientSecretEnvVar := accountType + "CLIENT_SECRET"
|
||||
applicationIdEnvVar := accountType + "APPLICATION_ID"
|
||||
|
@ -290,7 +289,7 @@ func getOAuthCredential(accountType string) (*azblob.TokenCredential, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
tc := azblob.NewTokenCredential(spt.Token().AccessToken, func(tc azblob.TokenCredential) time.Duration {
|
||||
tc := NewTokenCredential(spt.Token().AccessToken, func(tc TokenCredential) time.Duration {
|
||||
_ = spt.Refresh()
|
||||
return time.Until(spt.Token().Expires())
|
||||
})
|
||||
|
@ -298,36 +297,36 @@ func getOAuthCredential(accountType string) (*azblob.TokenCredential, error) {
|
|||
return &tc, nil
|
||||
}
|
||||
|
||||
func getGenericBSU(accountType string) (azblob.ServiceURL, error) {
|
||||
func getGenericBSU(accountType string) (ServiceURL, error) {
|
||||
credential, err := getGenericCredential(accountType)
|
||||
if err != nil {
|
||||
return azblob.ServiceURL{}, err
|
||||
return ServiceURL{}, err
|
||||
}
|
||||
|
||||
pipeline := azblob.NewPipeline(credential, azblob.PipelineOptions{})
|
||||
pipeline := NewPipeline(credential, PipelineOptions{})
|
||||
blobPrimaryURL, _ := url.Parse("https://" + credential.AccountName() + ".blob.core.windows.net/")
|
||||
return azblob.NewServiceURL(*blobPrimaryURL, pipeline), nil
|
||||
return NewServiceURL(*blobPrimaryURL, pipeline), nil
|
||||
}
|
||||
|
||||
func getBSU() azblob.ServiceURL {
|
||||
func getBSU() ServiceURL {
|
||||
bsu, _ := getGenericBSU("")
|
||||
return bsu
|
||||
}
|
||||
|
||||
func getAlternateBSU() (azblob.ServiceURL, error) {
|
||||
func getAlternateBSU() (ServiceURL, error) {
|
||||
return getGenericBSU("SECONDARY_")
|
||||
}
|
||||
|
||||
func getPremiumBSU() (azblob.ServiceURL, error) {
|
||||
func getPremiumBSU() (ServiceURL, error) {
|
||||
return getGenericBSU("PREMIUM_")
|
||||
}
|
||||
|
||||
func getBlobStorageBSU() (azblob.ServiceURL, error) {
|
||||
func getBlobStorageBSU() (ServiceURL, error) {
|
||||
return getGenericBSU("BLOB_STORAGE_")
|
||||
}
|
||||
|
||||
func validateStorageError(c *chk.C, err error, code azblob.ServiceCodeType) {
|
||||
serr, _ := err.(azblob.StorageError)
|
||||
func validateStorageError(c *chk.C, err error, code ServiceCodeType) {
|
||||
serr, _ := err.(StorageError)
|
||||
c.Assert(serr.ServiceCode(), chk.Equals, code)
|
||||
}
|
||||
|
||||
|
@ -348,10 +347,10 @@ func generateCurrentTimeWithModerateResolution() time.Time {
|
|||
// those changes not being reflected yet, we will wait 30 seconds and try the test again. If it fails this time for any reason,
|
||||
// we fail the test. It is the responsibility of the the testImplFunc to determine which error string indicates the test should be retried.
|
||||
// There can only be one such string. All errors that cannot be due to this detail should be asserted and not returned as an error string.
|
||||
func runTestRequiringServiceProperties(c *chk.C, bsu azblob.ServiceURL, code string,
|
||||
enableServicePropertyFunc func(*chk.C, azblob.ServiceURL),
|
||||
testImplFunc func(*chk.C, azblob.ServiceURL) error,
|
||||
disableServicePropertyFunc func(*chk.C, azblob.ServiceURL)) {
|
||||
func runTestRequiringServiceProperties(c *chk.C, bsu ServiceURL, code string,
|
||||
enableServicePropertyFunc func(*chk.C, ServiceURL),
|
||||
testImplFunc func(*chk.C, ServiceURL) error,
|
||||
disableServicePropertyFunc func(*chk.C, ServiceURL)) {
|
||||
enableServicePropertyFunc(c, bsu)
|
||||
defer disableServicePropertyFunc(c, bsu)
|
||||
err := testImplFunc(c, bsu)
|
||||
|
@ -363,19 +362,19 @@ func runTestRequiringServiceProperties(c *chk.C, bsu azblob.ServiceURL, code str
|
|||
}
|
||||
}
|
||||
|
||||
func enableSoftDelete(c *chk.C, bsu azblob.ServiceURL) {
|
||||
func enableSoftDelete(c *chk.C, bsu ServiceURL) {
|
||||
days := int32(1)
|
||||
_, err := bsu.SetProperties(ctx, azblob.StorageServiceProperties{DeleteRetentionPolicy: &azblob.RetentionPolicy{Enabled: true, Days: &days}})
|
||||
_, err := bsu.SetProperties(ctx, StorageServiceProperties{DeleteRetentionPolicy: &RetentionPolicy{Enabled: true, Days: &days}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
}
|
||||
|
||||
func disableSoftDelete(c *chk.C, bsu azblob.ServiceURL) {
|
||||
_, err := bsu.SetProperties(ctx, azblob.StorageServiceProperties{DeleteRetentionPolicy: &azblob.RetentionPolicy{Enabled: false}})
|
||||
func disableSoftDelete(c *chk.C, bsu ServiceURL) {
|
||||
_, err := bsu.SetProperties(ctx, StorageServiceProperties{DeleteRetentionPolicy: &RetentionPolicy{Enabled: false}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
}
|
||||
|
||||
func validateUpload(c *chk.C, blobURL azblob.BlockBlobURL) {
|
||||
resp, err := blobURL.Download(ctx, 0, 0, azblob.BlobAccessConditions{}, false)
|
||||
func validateUpload(c *chk.C, blobURL BlockBlobURL) {
|
||||
resp, err := blobURL.Download(ctx, 0, 0, BlobAccessConditions{}, false)
|
||||
c.Assert(err, chk.IsNil)
|
||||
data, _ := ioutil.ReadAll(resp.Response().Body)
|
||||
c.Assert(data, chk.HasLen, 0)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package azblob_test
|
||||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
@ -10,7 +10,6 @@ import (
|
|||
"bytes"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-storage-blob-go/azblob"
|
||||
chk "gopkg.in/check.v1" // go get gopkg.in/check.v1
|
||||
)
|
||||
|
||||
|
@ -21,23 +20,23 @@ func (s *aztestsSuite) TestAppendBlock(c *chk.C) {
|
|||
|
||||
blob := container.NewAppendBlobURL(generateBlobName())
|
||||
|
||||
resp, err := blob.Create(context.Background(), azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
resp, err := blob.Create(context.Background(), BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.StatusCode(), chk.Equals, 201)
|
||||
|
||||
appendResp, err := blob.AppendBlock(context.Background(), getReaderToRandomBytes(1024), azblob.AppendBlobAccessConditions{}, nil)
|
||||
appendResp, err := blob.AppendBlock(context.Background(), getReaderToRandomBytes(1024), AppendBlobAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(appendResp.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(appendResp.BlobAppendOffset(), chk.Equals, "0")
|
||||
c.Assert(appendResp.BlobCommittedBlockCount(), chk.Equals, int32(1))
|
||||
c.Assert(appendResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(appendResp.ETag(), chk.Not(chk.Equals), ETagNone)
|
||||
c.Assert(appendResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(appendResp.ContentMD5(), chk.Not(chk.Equals), "")
|
||||
c.Assert(appendResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(appendResp.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(appendResp.Date().IsZero(), chk.Equals, false)
|
||||
|
||||
appendResp, err = blob.AppendBlock(context.Background(), getReaderToRandomBytes(1024), azblob.AppendBlobAccessConditions{}, nil)
|
||||
appendResp, err = blob.AppendBlock(context.Background(), getReaderToRandomBytes(1024), AppendBlobAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(appendResp.BlobAppendOffset(), chk.Equals, "1024")
|
||||
c.Assert(appendResp.BlobCommittedBlockCount(), chk.Equals, int32(2))
|
||||
|
@ -50,19 +49,19 @@ func (s *aztestsSuite) TestAppendBlockWithMD5(c *chk.C) {
|
|||
|
||||
// set up blob to test
|
||||
blob := container.NewAppendBlobURL(generateBlobName())
|
||||
resp, err := blob.Create(context.Background(), azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
resp, err := blob.Create(context.Background(), BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.StatusCode(), chk.Equals, 201)
|
||||
|
||||
// test append block with valid MD5 value
|
||||
readerToBody, body := getRandomDataAndReader(1024)
|
||||
md5Value := md5.Sum(body)
|
||||
appendResp, err := blob.AppendBlock(context.Background(), readerToBody, azblob.AppendBlobAccessConditions{}, md5Value[:])
|
||||
appendResp, err := blob.AppendBlock(context.Background(), readerToBody, AppendBlobAccessConditions{}, md5Value[:])
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(appendResp.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(appendResp.BlobAppendOffset(), chk.Equals, "0")
|
||||
c.Assert(appendResp.BlobCommittedBlockCount(), chk.Equals, int32(1))
|
||||
c.Assert(appendResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(appendResp.ETag(), chk.Not(chk.Equals), ETagNone)
|
||||
c.Assert(appendResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(appendResp.ContentMD5(), chk.DeepEquals, md5Value[:])
|
||||
c.Assert(appendResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
|
@ -72,8 +71,8 @@ func (s *aztestsSuite) TestAppendBlockWithMD5(c *chk.C) {
|
|||
// test append block with bad MD5 value
|
||||
readerToBody, body = getRandomDataAndReader(1024)
|
||||
_, badMD5 := getRandomDataAndReader(16)
|
||||
appendResp, err = blob.AppendBlock(context.Background(), readerToBody, azblob.AppendBlobAccessConditions{}, badMD5[:])
|
||||
validateStorageError(c, err, azblob.ServiceCodeMd5Mismatch)
|
||||
appendResp, err = blob.AppendBlock(context.Background(), readerToBody, AppendBlobAccessConditions{}, badMD5[:])
|
||||
validateStorageError(c, err, ServiceCodeMd5Mismatch)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestAppendBlockFromURL(c *chk.C) {
|
||||
|
@ -92,15 +91,15 @@ func (s *aztestsSuite) TestAppendBlockFromURL(c *chk.C) {
|
|||
destBlob := container.NewAppendBlobURL(generateName("appenddest"))
|
||||
|
||||
// Prepare source blob for copy.
|
||||
cResp1, err := srcBlob.Create(context.Background(), azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
cResp1, err := srcBlob.Create(context.Background(), BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(cResp1.StatusCode(), chk.Equals, 201)
|
||||
appendResp, err := srcBlob.AppendBlock(context.Background(), r, azblob.AppendBlobAccessConditions{}, nil)
|
||||
appendResp, err := srcBlob.AppendBlock(context.Background(), r, AppendBlobAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(appendResp.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(appendResp.BlobAppendOffset(), chk.Equals, "0")
|
||||
c.Assert(appendResp.BlobCommittedBlockCount(), chk.Equals, int32(1))
|
||||
c.Assert(appendResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(appendResp.ETag(), chk.Not(chk.Equals), ETagNone)
|
||||
c.Assert(appendResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(appendResp.ContentMD5(), chk.Not(chk.Equals), "")
|
||||
c.Assert(appendResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
|
@ -108,14 +107,14 @@ func (s *aztestsSuite) TestAppendBlockFromURL(c *chk.C) {
|
|||
c.Assert(appendResp.Date().IsZero(), chk.Equals, false)
|
||||
|
||||
// Get source blob URL with SAS for AppendBlockFromURL.
|
||||
srcBlobParts := azblob.NewBlobURLParts(srcBlob.URL())
|
||||
srcBlobParts := NewBlobURLParts(srcBlob.URL())
|
||||
|
||||
srcBlobParts.SAS, err = azblob.BlobSASSignatureValues{
|
||||
Protocol: azblob.SASProtocolHTTPS, // Users MUST use HTTPS (not HTTP)
|
||||
srcBlobParts.SAS, err = BlobSASSignatureValues{
|
||||
Protocol: SASProtocolHTTPS, // Users MUST use HTTPS (not HTTP)
|
||||
ExpiryTime: time.Now().UTC().Add(48 * time.Hour), // 48-hours before expiration
|
||||
ContainerName: srcBlobParts.ContainerName,
|
||||
BlobName: srcBlobParts.BlobName,
|
||||
Permissions: azblob.BlobSASPermissions{Read: true}.String(),
|
||||
Permissions: BlobSASPermissions{Read: true}.String(),
|
||||
}.NewSASQueryParameters(credential)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
|
@ -124,15 +123,15 @@ func (s *aztestsSuite) TestAppendBlockFromURL(c *chk.C) {
|
|||
srcBlobURLWithSAS := srcBlobParts.URL()
|
||||
|
||||
// Append block from URL.
|
||||
cResp2, err := destBlob.Create(context.Background(), azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
cResp2, err := destBlob.Create(context.Background(), BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(cResp2.StatusCode(), chk.Equals, 201)
|
||||
appendFromURLResp, err := destBlob.AppendBlockFromURL(ctx, srcBlobURLWithSAS, 0, int64(testSize), azblob.AppendBlobAccessConditions{}, azblob.ModifiedAccessConditions{}, nil)
|
||||
appendFromURLResp, err := destBlob.AppendBlockFromURL(ctx, srcBlobURLWithSAS, 0, int64(testSize), AppendBlobAccessConditions{}, ModifiedAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(appendFromURLResp.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(appendFromURLResp.BlobAppendOffset(), chk.Equals, "0")
|
||||
c.Assert(appendFromURLResp.BlobCommittedBlockCount(), chk.Equals, int32(1))
|
||||
c.Assert(appendFromURLResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(appendFromURLResp.ETag(), chk.Not(chk.Equals), ETagNone)
|
||||
c.Assert(appendFromURLResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(appendFromURLResp.ContentMD5(), chk.Not(chk.Equals), "")
|
||||
c.Assert(appendFromURLResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
|
@ -140,9 +139,9 @@ func (s *aztestsSuite) TestAppendBlockFromURL(c *chk.C) {
|
|||
c.Assert(appendFromURLResp.Date().IsZero(), chk.Equals, false)
|
||||
|
||||
// Check data integrity through downloading.
|
||||
downloadResp, err := destBlob.BlobURL.Download(ctx, 0, azblob.CountToEnd, azblob.BlobAccessConditions{}, false)
|
||||
downloadResp, err := destBlob.BlobURL.Download(ctx, 0, CountToEnd, BlobAccessConditions{}, false)
|
||||
c.Assert(err, chk.IsNil)
|
||||
destData, err := ioutil.ReadAll(downloadResp.Body(azblob.RetryReaderOptions{}))
|
||||
destData, err := ioutil.ReadAll(downloadResp.Body(RetryReaderOptions{}))
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(destData, chk.DeepEquals, sourceData)
|
||||
}
|
||||
|
@ -164,15 +163,15 @@ func (s *aztestsSuite) TestAppendBlockFromURLWithMD5(c *chk.C) {
|
|||
destBlob := container.NewAppendBlobURL(generateName("appenddest"))
|
||||
|
||||
// Prepare source blob for copy.
|
||||
cResp1, err := srcBlob.Create(context.Background(), azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
cResp1, err := srcBlob.Create(context.Background(), BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(cResp1.StatusCode(), chk.Equals, 201)
|
||||
appendResp, err := srcBlob.AppendBlock(context.Background(), r, azblob.AppendBlobAccessConditions{}, nil)
|
||||
appendResp, err := srcBlob.AppendBlock(context.Background(), r, AppendBlobAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(appendResp.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(appendResp.BlobAppendOffset(), chk.Equals, "0")
|
||||
c.Assert(appendResp.BlobCommittedBlockCount(), chk.Equals, int32(1))
|
||||
c.Assert(appendResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(appendResp.ETag(), chk.Not(chk.Equals), ETagNone)
|
||||
c.Assert(appendResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(appendResp.ContentMD5(), chk.Not(chk.Equals), "")
|
||||
c.Assert(appendResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
|
@ -180,14 +179,14 @@ func (s *aztestsSuite) TestAppendBlockFromURLWithMD5(c *chk.C) {
|
|||
c.Assert(appendResp.Date().IsZero(), chk.Equals, false)
|
||||
|
||||
// Get source blob URL with SAS for AppendBlockFromURL.
|
||||
srcBlobParts := azblob.NewBlobURLParts(srcBlob.URL())
|
||||
srcBlobParts := NewBlobURLParts(srcBlob.URL())
|
||||
|
||||
srcBlobParts.SAS, err = azblob.BlobSASSignatureValues{
|
||||
Protocol: azblob.SASProtocolHTTPS, // Users MUST use HTTPS (not HTTP)
|
||||
srcBlobParts.SAS, err = BlobSASSignatureValues{
|
||||
Protocol: SASProtocolHTTPS, // Users MUST use HTTPS (not HTTP)
|
||||
ExpiryTime: time.Now().UTC().Add(48 * time.Hour), // 48-hours before expiration
|
||||
ContainerName: srcBlobParts.ContainerName,
|
||||
BlobName: srcBlobParts.BlobName,
|
||||
Permissions: azblob.BlobSASPermissions{Read: true}.String(),
|
||||
Permissions: BlobSASPermissions{Read: true}.String(),
|
||||
}.NewSASQueryParameters(credential)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
|
@ -196,15 +195,15 @@ func (s *aztestsSuite) TestAppendBlockFromURLWithMD5(c *chk.C) {
|
|||
srcBlobURLWithSAS := srcBlobParts.URL()
|
||||
|
||||
// Append block from URL.
|
||||
cResp2, err := destBlob.Create(context.Background(), azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
cResp2, err := destBlob.Create(context.Background(), BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(cResp2.StatusCode(), chk.Equals, 201)
|
||||
appendFromURLResp, err := destBlob.AppendBlockFromURL(ctx, srcBlobURLWithSAS, 0, int64(testSize), azblob.AppendBlobAccessConditions{}, azblob.ModifiedAccessConditions{}, md5Value[:])
|
||||
appendFromURLResp, err := destBlob.AppendBlockFromURL(ctx, srcBlobURLWithSAS, 0, int64(testSize), AppendBlobAccessConditions{}, ModifiedAccessConditions{}, md5Value[:])
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(appendFromURLResp.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(appendFromURLResp.BlobAppendOffset(), chk.Equals, "0")
|
||||
c.Assert(appendFromURLResp.BlobCommittedBlockCount(), chk.Equals, int32(1))
|
||||
c.Assert(appendFromURLResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(appendFromURLResp.ETag(), chk.Not(chk.Equals), ETagNone)
|
||||
c.Assert(appendFromURLResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(appendFromURLResp.ContentMD5(), chk.DeepEquals, md5Value[:])
|
||||
c.Assert(appendFromURLResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
|
@ -212,16 +211,16 @@ func (s *aztestsSuite) TestAppendBlockFromURLWithMD5(c *chk.C) {
|
|||
c.Assert(appendFromURLResp.Date().IsZero(), chk.Equals, false)
|
||||
|
||||
// Check data integrity through downloading.
|
||||
downloadResp, err := destBlob.BlobURL.Download(ctx, 0, azblob.CountToEnd, azblob.BlobAccessConditions{}, false)
|
||||
downloadResp, err := destBlob.BlobURL.Download(ctx, 0, CountToEnd, BlobAccessConditions{}, false)
|
||||
c.Assert(err, chk.IsNil)
|
||||
destData, err := ioutil.ReadAll(downloadResp.Body(azblob.RetryReaderOptions{}))
|
||||
destData, err := ioutil.ReadAll(downloadResp.Body(RetryReaderOptions{}))
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(destData, chk.DeepEquals, sourceData)
|
||||
|
||||
// Test append block from URL with bad MD5 value
|
||||
_, badMD5 := getRandomDataAndReader(16)
|
||||
_, err = destBlob.AppendBlockFromURL(ctx, srcBlobURLWithSAS, 0, int64(testSize), azblob.AppendBlobAccessConditions{}, azblob.ModifiedAccessConditions{}, badMD5)
|
||||
validateStorageError(c, err, azblob.ServiceCodeMd5Mismatch)
|
||||
_, err = destBlob.AppendBlockFromURL(ctx, srcBlobURLWithSAS, 0, int64(testSize), AppendBlobAccessConditions{}, ModifiedAccessConditions{}, badMD5)
|
||||
validateStorageError(c, err, ServiceCodeMd5Mismatch)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobCreateAppendMetadataNonEmpty(c *chk.C) {
|
||||
|
@ -230,10 +229,10 @@ func (s *aztestsSuite) TestBlobCreateAppendMetadataNonEmpty(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getAppendBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.Create(ctx, azblob.BlobHTTPHeaders{}, basicMetadata, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.Create(ctx, BlobHTTPHeaders{}, basicMetadata, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
|
||||
}
|
||||
|
@ -244,10 +243,10 @@ func (s *aztestsSuite) TestBlobCreateAppendMetadataEmpty(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getAppendBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.Create(ctx, azblob.BlobHTTPHeaders{}, azblob.Metadata{}, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.Create(ctx, BlobHTTPHeaders{}, Metadata{}, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.NewMetadata(), chk.HasLen, 0)
|
||||
}
|
||||
|
@ -258,7 +257,7 @@ func (s *aztestsSuite) TestBlobCreateAppendMetadataInvalid(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getAppendBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.Create(ctx, azblob.BlobHTTPHeaders{}, azblob.Metadata{"In valid!": "bar"}, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.Create(ctx, BlobHTTPHeaders{}, Metadata{"In valid!": "bar"}, BlobAccessConditions{})
|
||||
c.Assert(strings.Contains(err.Error(), invalidHeaderErrorSubstring), chk.Equals, true)
|
||||
}
|
||||
|
||||
|
@ -268,17 +267,17 @@ func (s *aztestsSuite) TestBlobCreateAppendHTTPHeaders(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getAppendBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.Create(ctx, basicHeaders, nil, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.Create(ctx, basicHeaders, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
h := resp.NewHTTPHeaders()
|
||||
c.Assert(h, chk.DeepEquals, basicHeaders)
|
||||
}
|
||||
|
||||
func validateAppendBlobPut(c *chk.C, blobURL azblob.AppendBlobURL) {
|
||||
resp, err := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
func validateAppendBlobPut(c *chk.C, blobURL AppendBlobURL) {
|
||||
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
|
||||
}
|
||||
|
@ -291,8 +290,8 @@ func (s *aztestsSuite) TestBlobCreateAppendIfModifiedSinceTrue(c *chk.C) {
|
|||
|
||||
currentTime := getRelativeTimeGMT(-10)
|
||||
|
||||
_, err := blobURL.Create(ctx, azblob.BlobHTTPHeaders{}, basicMetadata,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
_, err := blobURL.Create(ctx, BlobHTTPHeaders{}, basicMetadata,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateAppendBlobPut(c, blobURL)
|
||||
|
@ -306,9 +305,9 @@ func (s *aztestsSuite) TestBlobCreateAppendIfModifiedSinceFalse(c *chk.C) {
|
|||
|
||||
currentTime := getRelativeTimeGMT(10)
|
||||
|
||||
_, err := blobURL.Create(ctx, azblob.BlobHTTPHeaders{}, basicMetadata,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
_, err := blobURL.Create(ctx, BlobHTTPHeaders{}, basicMetadata,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobCreateAppendIfUnmodifiedSinceTrue(c *chk.C) {
|
||||
|
@ -319,8 +318,8 @@ func (s *aztestsSuite) TestBlobCreateAppendIfUnmodifiedSinceTrue(c *chk.C) {
|
|||
|
||||
currentTime := getRelativeTimeGMT(10)
|
||||
|
||||
_, err := blobURL.Create(ctx, azblob.BlobHTTPHeaders{}, basicMetadata,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
_, err := blobURL.Create(ctx, BlobHTTPHeaders{}, basicMetadata,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateAppendBlobPut(c, blobURL)
|
||||
|
@ -334,9 +333,9 @@ func (s *aztestsSuite) TestBlobCreateAppendIfUnmodifiedSinceFalse(c *chk.C) {
|
|||
|
||||
currentTime := getRelativeTimeGMT(-10)
|
||||
|
||||
_, err := blobURL.Create(ctx, azblob.BlobHTTPHeaders{}, basicMetadata,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
_, err := blobURL.Create(ctx, BlobHTTPHeaders{}, basicMetadata,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobCreateAppendIfMatchTrue(c *chk.C) {
|
||||
|
@ -345,10 +344,10 @@ func (s *aztestsSuite) TestBlobCreateAppendIfMatchTrue(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := createNewAppendBlob(c, containerURL)
|
||||
|
||||
resp, _ := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
|
||||
_, err := blobURL.Create(ctx, azblob.BlobHTTPHeaders{}, basicMetadata,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfMatch: resp.ETag()}})
|
||||
_, err := blobURL.Create(ctx, BlobHTTPHeaders{}, basicMetadata,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: resp.ETag()}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateAppendBlobPut(c, blobURL)
|
||||
|
@ -360,9 +359,9 @@ func (s *aztestsSuite) TestBlobCreateAppendIfMatchFalse(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := createNewAppendBlob(c, containerURL)
|
||||
|
||||
_, err := blobURL.Create(ctx, azblob.BlobHTTPHeaders{}, basicMetadata,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfMatch: azblob.ETag("garbage")}})
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
_, err := blobURL.Create(ctx, BlobHTTPHeaders{}, basicMetadata,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: ETag("garbage")}})
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobCreateAppendIfNoneMatchTrue(c *chk.C) {
|
||||
|
@ -371,8 +370,8 @@ func (s *aztestsSuite) TestBlobCreateAppendIfNoneMatchTrue(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := createNewAppendBlob(c, containerURL)
|
||||
|
||||
_, err := blobURL.Create(ctx, azblob.BlobHTTPHeaders{}, basicMetadata,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfNoneMatch: azblob.ETag("garbage")}})
|
||||
_, err := blobURL.Create(ctx, BlobHTTPHeaders{}, basicMetadata,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: ETag("garbage")}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateAppendBlobPut(c, blobURL)
|
||||
|
@ -384,11 +383,11 @@ func (s *aztestsSuite) TestBlobCreateAppendIfNoneMatchFalse(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := createNewAppendBlob(c, containerURL)
|
||||
|
||||
resp, _ := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
|
||||
_, err := blobURL.Create(ctx, azblob.BlobHTTPHeaders{}, basicMetadata,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfNoneMatch: resp.ETag()}})
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
_, err := blobURL.Create(ctx, BlobHTTPHeaders{}, basicMetadata,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: resp.ETag()}})
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobAppendBlockNilBody(c *chk.C) {
|
||||
|
@ -397,9 +396,9 @@ func (s *aztestsSuite) TestBlobAppendBlockNilBody(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := createNewAppendBlob(c, containerURL)
|
||||
|
||||
_, err := blobURL.AppendBlock(ctx, bytes.NewReader(nil), azblob.AppendBlobAccessConditions{}, nil)
|
||||
_, err := blobURL.AppendBlock(ctx, bytes.NewReader(nil), AppendBlobAccessConditions{}, nil)
|
||||
c.Assert(err, chk.NotNil)
|
||||
validateStorageError(c, err, azblob.ServiceCodeInvalidHeaderValue)
|
||||
validateStorageError(c, err, ServiceCodeInvalidHeaderValue)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobAppendBlockEmptyBody(c *chk.C) {
|
||||
|
@ -408,8 +407,8 @@ func (s *aztestsSuite) TestBlobAppendBlockEmptyBody(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := createNewAppendBlob(c, containerURL)
|
||||
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(""), azblob.AppendBlobAccessConditions{}, nil)
|
||||
validateStorageError(c, err, azblob.ServiceCodeInvalidHeaderValue)
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(""), AppendBlobAccessConditions{}, nil)
|
||||
validateStorageError(c, err, ServiceCodeInvalidHeaderValue)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobAppendBlockNonExistantBlob(c *chk.C) {
|
||||
|
@ -418,12 +417,12 @@ func (s *aztestsSuite) TestBlobAppendBlockNonExistantBlob(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getAppendBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData), azblob.AppendBlobAccessConditions{}, nil)
|
||||
validateStorageError(c, err, azblob.ServiceCodeBlobNotFound)
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData), AppendBlobAccessConditions{}, nil)
|
||||
validateStorageError(c, err, ServiceCodeBlobNotFound)
|
||||
}
|
||||
|
||||
func validateBlockAppended(c *chk.C, blobURL azblob.AppendBlobURL, expectedSize int) {
|
||||
resp, err := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
func validateBlockAppended(c *chk.C, blobURL AppendBlobURL, expectedSize int) {
|
||||
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.ContentLength(), chk.Equals, int64(expectedSize))
|
||||
}
|
||||
|
@ -437,7 +436,7 @@ func (s *aztestsSuite) TestBlobAppendBlockIfModifiedSinceTrue(c *chk.C) {
|
|||
currentTime := getRelativeTimeGMT(-10)
|
||||
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData),
|
||||
azblob.AppendBlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfModifiedSince: currentTime}}, nil)
|
||||
AppendBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateBlockAppended(c, blobURL, len(blockBlobDefaultData))
|
||||
|
@ -451,8 +450,8 @@ func (s *aztestsSuite) TestBlobAppendBlockIfModifiedSinceFalse(c *chk.C) {
|
|||
|
||||
currentTime := getRelativeTimeGMT(10)
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData),
|
||||
azblob.AppendBlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfModifiedSince: currentTime}}, nil)
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
AppendBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}}, nil)
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobAppendBlockIfUnmodifiedSinceTrue(c *chk.C) {
|
||||
|
@ -463,7 +462,7 @@ func (s *aztestsSuite) TestBlobAppendBlockIfUnmodifiedSinceTrue(c *chk.C) {
|
|||
|
||||
currentTime := getRelativeTimeGMT(10)
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData),
|
||||
azblob.AppendBlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, nil)
|
||||
AppendBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateBlockAppended(c, blobURL, len(blockBlobDefaultData))
|
||||
|
@ -477,8 +476,8 @@ func (s *aztestsSuite) TestBlobAppendBlockIfUnmodifiedSinceFalse(c *chk.C) {
|
|||
|
||||
currentTime := getRelativeTimeGMT(-10)
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData),
|
||||
azblob.AppendBlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, nil)
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
AppendBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}}, nil)
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobAppendBlockIfMatchTrue(c *chk.C) {
|
||||
|
@ -487,10 +486,10 @@ func (s *aztestsSuite) TestBlobAppendBlockIfMatchTrue(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := createNewAppendBlob(c, containerURL)
|
||||
|
||||
resp, _ := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData),
|
||||
azblob.AppendBlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfMatch: resp.ETag()}}, nil)
|
||||
AppendBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: resp.ETag()}}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateBlockAppended(c, blobURL, len(blockBlobDefaultData))
|
||||
|
@ -503,8 +502,8 @@ func (s *aztestsSuite) TestBlobAppendBlockIfMatchFalse(c *chk.C) {
|
|||
blobURL, _ := createNewAppendBlob(c, containerURL)
|
||||
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData),
|
||||
azblob.AppendBlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfMatch: azblob.ETag("garbage")}}, nil)
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
AppendBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: ETag("garbage")}}, nil)
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobAppendBlockIfNoneMatchTrue(c *chk.C) {
|
||||
|
@ -514,7 +513,7 @@ func (s *aztestsSuite) TestBlobAppendBlockIfNoneMatchTrue(c *chk.C) {
|
|||
blobURL, _ := createNewAppendBlob(c, containerURL)
|
||||
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData),
|
||||
azblob.AppendBlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfNoneMatch: azblob.ETag("garbage")}}, nil)
|
||||
AppendBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: ETag("garbage")}}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateBlockAppended(c, blobURL, len(blockBlobDefaultData))
|
||||
|
@ -526,11 +525,11 @@ func (s *aztestsSuite) TestBlobAppendBlockIfNoneMatchFalse(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := createNewAppendBlob(c, containerURL)
|
||||
|
||||
resp, _ := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData),
|
||||
azblob.AppendBlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfNoneMatch: resp.ETag()}}, nil)
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
AppendBlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: resp.ETag()}}, nil)
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobAppendBlockIfAppendPositionMatchTrueNegOne(c *chk.C) {
|
||||
|
@ -540,7 +539,7 @@ func (s *aztestsSuite) TestBlobAppendBlockIfAppendPositionMatchTrueNegOne(c *chk
|
|||
blobURL, _ := createNewAppendBlob(c, containerURL)
|
||||
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData),
|
||||
azblob.AppendBlobAccessConditions{AppendPositionAccessConditions: azblob.AppendPositionAccessConditions{IfAppendPositionEqual: -1}}, nil) // This will cause the library to set the value of the header to 0
|
||||
AppendBlobAccessConditions{AppendPositionAccessConditions: AppendPositionAccessConditions{IfAppendPositionEqual: -1}}, nil) // This will cause the library to set the value of the header to 0
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateBlockAppended(c, blobURL, len(blockBlobDefaultData))
|
||||
|
@ -552,10 +551,10 @@ func (s *aztestsSuite) TestBlobAppendBlockIfAppendPositionMatchZero(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := createNewAppendBlob(c, containerURL)
|
||||
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData), azblob.AppendBlobAccessConditions{}, nil) // The position will not match, but the condition should be ignored
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData), AppendBlobAccessConditions{}, nil) // The position will not match, but the condition should be ignored
|
||||
c.Assert(err, chk.IsNil)
|
||||
_, err = blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData),
|
||||
azblob.AppendBlobAccessConditions{AppendPositionAccessConditions: azblob.AppendPositionAccessConditions{IfAppendPositionEqual: 0}}, nil)
|
||||
AppendBlobAccessConditions{AppendPositionAccessConditions: AppendPositionAccessConditions{IfAppendPositionEqual: 0}}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateBlockAppended(c, blobURL, 2*len(blockBlobDefaultData))
|
||||
|
@ -567,10 +566,10 @@ func (s *aztestsSuite) TestBlobAppendBlockIfAppendPositionMatchTrueNonZero(c *ch
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := createNewAppendBlob(c, containerURL)
|
||||
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData), azblob.AppendBlobAccessConditions{}, nil)
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData), AppendBlobAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
_, err = blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData),
|
||||
azblob.AppendBlobAccessConditions{AppendPositionAccessConditions: azblob.AppendPositionAccessConditions{IfAppendPositionEqual: int64(len(blockBlobDefaultData))}}, nil)
|
||||
AppendBlobAccessConditions{AppendPositionAccessConditions: AppendPositionAccessConditions{IfAppendPositionEqual: int64(len(blockBlobDefaultData))}}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateBlockAppended(c, blobURL, len(blockBlobDefaultData)*2)
|
||||
|
@ -582,11 +581,11 @@ func (s *aztestsSuite) TestBlobAppendBlockIfAppendPositionMatchFalseNegOne(c *ch
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := createNewAppendBlob(c, containerURL)
|
||||
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData), azblob.AppendBlobAccessConditions{}, nil)
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData), AppendBlobAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
_, err = blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData),
|
||||
azblob.AppendBlobAccessConditions{AppendPositionAccessConditions: azblob.AppendPositionAccessConditions{IfAppendPositionEqual: -1}}, nil) // This will cause the library to set the value of the header to 0
|
||||
validateStorageError(c, err, azblob.ServiceCodeAppendPositionConditionNotMet)
|
||||
AppendBlobAccessConditions{AppendPositionAccessConditions: AppendPositionAccessConditions{IfAppendPositionEqual: -1}}, nil) // This will cause the library to set the value of the header to 0
|
||||
validateStorageError(c, err, ServiceCodeAppendPositionConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobAppendBlockIfAppendPositionMatchFalseNonZero(c *chk.C) {
|
||||
|
@ -596,8 +595,8 @@ func (s *aztestsSuite) TestBlobAppendBlockIfAppendPositionMatchFalseNonZero(c *c
|
|||
blobURL, _ := createNewAppendBlob(c, containerURL)
|
||||
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData),
|
||||
azblob.AppendBlobAccessConditions{AppendPositionAccessConditions: azblob.AppendPositionAccessConditions{IfAppendPositionEqual: 12}}, nil)
|
||||
validateStorageError(c, err, azblob.ServiceCodeAppendPositionConditionNotMet)
|
||||
AppendBlobAccessConditions{AppendPositionAccessConditions: AppendPositionAccessConditions{IfAppendPositionEqual: 12}}, nil)
|
||||
validateStorageError(c, err, ServiceCodeAppendPositionConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobAppendBlockIfMaxSizeTrue(c *chk.C) {
|
||||
|
@ -607,7 +606,7 @@ func (s *aztestsSuite) TestBlobAppendBlockIfMaxSizeTrue(c *chk.C) {
|
|||
blobURL, _ := createNewAppendBlob(c, containerURL)
|
||||
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData),
|
||||
azblob.AppendBlobAccessConditions{AppendPositionAccessConditions: azblob.AppendPositionAccessConditions{IfMaxSizeLessThanOrEqual: int64(len(blockBlobDefaultData) + 1)}}, nil)
|
||||
AppendBlobAccessConditions{AppendPositionAccessConditions: AppendPositionAccessConditions{IfMaxSizeLessThanOrEqual: int64(len(blockBlobDefaultData) + 1)}}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateBlockAppended(c, blobURL, len(blockBlobDefaultData))
|
||||
|
@ -620,6 +619,6 @@ func (s *aztestsSuite) TestBlobAppendBlockIfMaxSizeFalse(c *chk.C) {
|
|||
blobURL, _ := createNewAppendBlob(c, containerURL)
|
||||
|
||||
_, err := blobURL.AppendBlock(ctx, strings.NewReader(blockBlobDefaultData),
|
||||
azblob.AppendBlobAccessConditions{AppendPositionAccessConditions: azblob.AppendPositionAccessConditions{IfMaxSizeLessThanOrEqual: int64(len(blockBlobDefaultData) - 1)}}, nil)
|
||||
validateStorageError(c, err, azblob.ServiceCodeMaxBlobSizeConditionNotMet)
|
||||
AppendBlobAccessConditions{AppendPositionAccessConditions: AppendPositionAccessConditions{IfMaxSizeLessThanOrEqual: int64(len(blockBlobDefaultData) - 1)}}, nil)
|
||||
validateStorageError(c, err, ServiceCodeMaxBlobSizeConditionNotMet)
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,10 +1,12 @@
|
|||
package azblob_test
|
||||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"time"
|
||||
|
||||
"crypto/md5"
|
||||
|
@ -12,7 +14,7 @@ import (
|
|||
"bytes"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-storage-blob-go/azblob"
|
||||
guuid "github.com/google/uuid"
|
||||
chk "gopkg.in/check.v1" // go get gopkg.in/check.v1
|
||||
)
|
||||
|
||||
|
@ -25,7 +27,7 @@ func (s *aztestsSuite) TestStageGetBlocks(c *chk.C) {
|
|||
|
||||
blockID := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%6d", 0)))
|
||||
|
||||
putResp, err := blob.StageBlock(context.Background(), blockID, getReaderToRandomBytes(1024), azblob.LeaseAccessConditions{}, nil)
|
||||
putResp, err := blob.StageBlock(context.Background(), blockID, getReaderToRandomBytes(1024), LeaseAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(putResp.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(putResp.ContentMD5(), chk.Not(chk.Equals), "")
|
||||
|
@ -33,11 +35,11 @@ func (s *aztestsSuite) TestStageGetBlocks(c *chk.C) {
|
|||
c.Assert(putResp.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(putResp.Date().IsZero(), chk.Equals, false)
|
||||
|
||||
blockList, err := blob.GetBlockList(context.Background(), azblob.BlockListAll, azblob.LeaseAccessConditions{})
|
||||
blockList, err := blob.GetBlockList(context.Background(), BlockListAll, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(blockList.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(blockList.LastModified().IsZero(), chk.Equals, true)
|
||||
c.Assert(blockList.ETag(), chk.Equals, azblob.ETagNone)
|
||||
c.Assert(blockList.ETag(), chk.Equals, ETagNone)
|
||||
c.Assert(blockList.ContentType(), chk.Not(chk.Equals), "")
|
||||
c.Assert(blockList.BlobContentLength(), chk.Equals, int64(-1))
|
||||
c.Assert(blockList.RequestID(), chk.Not(chk.Equals), "")
|
||||
|
@ -46,21 +48,21 @@ func (s *aztestsSuite) TestStageGetBlocks(c *chk.C) {
|
|||
c.Assert(blockList.CommittedBlocks, chk.HasLen, 0)
|
||||
c.Assert(blockList.UncommittedBlocks, chk.HasLen, 1)
|
||||
|
||||
listResp, err := blob.CommitBlockList(context.Background(), []string{blockID}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
listResp, err := blob.CommitBlockList(context.Background(), []string{blockID}, BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(listResp.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(listResp.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(listResp.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(listResp.ETag(), chk.Not(chk.Equals), ETagNone)
|
||||
c.Assert(listResp.ContentMD5(), chk.Not(chk.Equals), "")
|
||||
c.Assert(listResp.RequestID(), chk.Not(chk.Equals), "")
|
||||
c.Assert(listResp.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(listResp.Date().IsZero(), chk.Equals, false)
|
||||
|
||||
blockList, err = blob.GetBlockList(context.Background(), azblob.BlockListAll, azblob.LeaseAccessConditions{})
|
||||
blockList, err = blob.GetBlockList(context.Background(), BlockListAll, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(blockList.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(blockList.LastModified().IsZero(), chk.Equals, false)
|
||||
c.Assert(blockList.ETag(), chk.Not(chk.Equals), azblob.ETagNone)
|
||||
c.Assert(blockList.ETag(), chk.Not(chk.Equals), ETagNone)
|
||||
c.Assert(blockList.ContentType(), chk.Not(chk.Equals), "")
|
||||
c.Assert(blockList.BlobContentLength(), chk.Equals, int64(1024))
|
||||
c.Assert(blockList.RequestID(), chk.Not(chk.Equals), "")
|
||||
|
@ -86,19 +88,19 @@ func (s *aztestsSuite) TestStageBlockFromURL(c *chk.C) {
|
|||
destBlob := container.NewBlockBlobURL(generateBlobName())
|
||||
|
||||
// Prepare source blob for copy.
|
||||
uploadSrcResp, err := srcBlob.Upload(ctx, r, azblob.BlobHTTPHeaders{}, azblob.Metadata{}, azblob.BlobAccessConditions{})
|
||||
uploadSrcResp, err := srcBlob.Upload(ctx, r, BlobHTTPHeaders{}, Metadata{}, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(uploadSrcResp.Response().StatusCode, chk.Equals, 201)
|
||||
|
||||
// Get source blob URL with SAS for StageFromURL.
|
||||
srcBlobParts := azblob.NewBlobURLParts(srcBlob.URL())
|
||||
srcBlobParts := NewBlobURLParts(srcBlob.URL())
|
||||
|
||||
srcBlobParts.SAS, err = azblob.BlobSASSignatureValues{
|
||||
Protocol: azblob.SASProtocolHTTPS, // Users MUST use HTTPS (not HTTP)
|
||||
srcBlobParts.SAS, err = BlobSASSignatureValues{
|
||||
Protocol: SASProtocolHTTPS, // Users MUST use HTTPS (not HTTP)
|
||||
ExpiryTime: time.Now().UTC().Add(48 * time.Hour), // 48-hours before expiration
|
||||
ContainerName: srcBlobParts.ContainerName,
|
||||
BlobName: srcBlobParts.BlobName,
|
||||
Permissions: azblob.BlobSASPermissions{Read: true}.String(),
|
||||
Permissions: BlobSASPermissions{Read: true}.String(),
|
||||
}.NewSASQueryParameters(credential)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
|
@ -108,7 +110,7 @@ func (s *aztestsSuite) TestStageBlockFromURL(c *chk.C) {
|
|||
|
||||
// Stage blocks from URL.
|
||||
blockID1, blockID2 := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%6d", 0))), base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%6d", 1)))
|
||||
stageResp1, err := destBlob.StageBlockFromURL(ctx, blockID1, srcBlobURLWithSAS, 0, 4*1024*1024, azblob.LeaseAccessConditions{}, azblob.ModifiedAccessConditions{})
|
||||
stageResp1, err := destBlob.StageBlockFromURL(ctx, blockID1, srcBlobURLWithSAS, 0, 4*1024*1024, LeaseAccessConditions{}, ModifiedAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(stageResp1.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(stageResp1.ContentMD5(), chk.Not(chk.Equals), "")
|
||||
|
@ -116,7 +118,7 @@ func (s *aztestsSuite) TestStageBlockFromURL(c *chk.C) {
|
|||
c.Assert(stageResp1.Version(), chk.Not(chk.Equals), "")
|
||||
c.Assert(stageResp1.Date().IsZero(), chk.Equals, false)
|
||||
|
||||
stageResp2, err := destBlob.StageBlockFromURL(ctx, blockID2, srcBlobURLWithSAS, 4*1024*1024, azblob.CountToEnd, azblob.LeaseAccessConditions{}, azblob.ModifiedAccessConditions{})
|
||||
stageResp2, err := destBlob.StageBlockFromURL(ctx, blockID2, srcBlobURLWithSAS, 4*1024*1024, CountToEnd, LeaseAccessConditions{}, ModifiedAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(stageResp2.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(stageResp2.ContentMD5(), chk.Not(chk.Equals), "")
|
||||
|
@ -125,21 +127,21 @@ func (s *aztestsSuite) TestStageBlockFromURL(c *chk.C) {
|
|||
c.Assert(stageResp2.Date().IsZero(), chk.Equals, false)
|
||||
|
||||
// Check block list.
|
||||
blockList, err := destBlob.GetBlockList(context.Background(), azblob.BlockListAll, azblob.LeaseAccessConditions{})
|
||||
blockList, err := destBlob.GetBlockList(context.Background(), BlockListAll, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(blockList.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(blockList.CommittedBlocks, chk.HasLen, 0)
|
||||
c.Assert(blockList.UncommittedBlocks, chk.HasLen, 2)
|
||||
|
||||
// Commit block list.
|
||||
listResp, err := destBlob.CommitBlockList(context.Background(), []string{blockID1, blockID2}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
listResp, err := destBlob.CommitBlockList(context.Background(), []string{blockID1, blockID2}, BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(listResp.Response().StatusCode, chk.Equals, 201)
|
||||
|
||||
// Check data integrity through downloading.
|
||||
downloadResp, err := destBlob.BlobURL.Download(ctx, 0, azblob.CountToEnd, azblob.BlobAccessConditions{}, false)
|
||||
downloadResp, err := destBlob.BlobURL.Download(ctx, 0, CountToEnd, BlobAccessConditions{}, false)
|
||||
c.Assert(err, chk.IsNil)
|
||||
destData, err := ioutil.ReadAll(downloadResp.Body(azblob.RetryReaderOptions{}))
|
||||
destData, err := ioutil.ReadAll(downloadResp.Body(RetryReaderOptions{}))
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(destData, chk.DeepEquals, sourceData)
|
||||
}
|
||||
|
@ -161,19 +163,19 @@ func (s *aztestsSuite) TestCopyBlockBlobFromURL(c *chk.C) {
|
|||
destBlob := container.NewBlockBlobURL(generateBlobName())
|
||||
|
||||
// Prepare source blob for copy.
|
||||
uploadSrcResp, err := srcBlob.Upload(ctx, r, azblob.BlobHTTPHeaders{}, azblob.Metadata{}, azblob.BlobAccessConditions{})
|
||||
uploadSrcResp, err := srcBlob.Upload(ctx, r, BlobHTTPHeaders{}, Metadata{}, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(uploadSrcResp.Response().StatusCode, chk.Equals, 201)
|
||||
|
||||
// Get source blob URL with SAS for StageFromURL.
|
||||
srcBlobParts := azblob.NewBlobURLParts(srcBlob.URL())
|
||||
srcBlobParts := NewBlobURLParts(srcBlob.URL())
|
||||
|
||||
srcBlobParts.SAS, err = azblob.BlobSASSignatureValues{
|
||||
Protocol: azblob.SASProtocolHTTPS, // Users MUST use HTTPS (not HTTP)
|
||||
srcBlobParts.SAS, err = BlobSASSignatureValues{
|
||||
Protocol: SASProtocolHTTPS, // Users MUST use HTTPS (not HTTP)
|
||||
ExpiryTime: time.Now().UTC().Add(48 * time.Hour), // 48-hours before expiration
|
||||
ContainerName: srcBlobParts.ContainerName,
|
||||
BlobName: srcBlobParts.BlobName,
|
||||
Permissions: azblob.BlobSASPermissions{Read: true}.String(),
|
||||
Permissions: BlobSASPermissions{Read: true}.String(),
|
||||
}.NewSASQueryParameters(credential)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
|
@ -182,7 +184,7 @@ func (s *aztestsSuite) TestCopyBlockBlobFromURL(c *chk.C) {
|
|||
srcBlobURLWithSAS := srcBlobParts.URL()
|
||||
|
||||
// Invoke copy blob from URL.
|
||||
resp, err := destBlob.CopyFromURL(ctx, srcBlobURLWithSAS, azblob.Metadata{"foo": "bar"}, azblob.ModifiedAccessConditions{}, azblob.BlobAccessConditions{}, sourceDataMD5Value[:])
|
||||
resp, err := destBlob.CopyFromURL(ctx, srcBlobURLWithSAS, Metadata{"foo": "bar"}, ModifiedAccessConditions{}, BlobAccessConditions{}, sourceDataMD5Value[:])
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 202)
|
||||
c.Assert(resp.ETag(), chk.Not(chk.Equals), "")
|
||||
|
@ -194,9 +196,9 @@ func (s *aztestsSuite) TestCopyBlockBlobFromURL(c *chk.C) {
|
|||
c.Assert(string(resp.CopyStatus()), chk.DeepEquals, "success")
|
||||
|
||||
// Check data integrity through downloading.
|
||||
downloadResp, err := destBlob.BlobURL.Download(ctx, 0, azblob.CountToEnd, azblob.BlobAccessConditions{}, false)
|
||||
downloadResp, err := destBlob.BlobURL.Download(ctx, 0, CountToEnd, BlobAccessConditions{}, false)
|
||||
c.Assert(err, chk.IsNil)
|
||||
destData, err := ioutil.ReadAll(downloadResp.Body(azblob.RetryReaderOptions{}))
|
||||
destData, err := ioutil.ReadAll(downloadResp.Body(RetryReaderOptions{}))
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(destData, chk.DeepEquals, sourceData)
|
||||
|
||||
|
@ -205,11 +207,11 @@ func (s *aztestsSuite) TestCopyBlockBlobFromURL(c *chk.C) {
|
|||
|
||||
// Edge case 1: Provide bad MD5 and make sure the copy fails
|
||||
_, badMD5 := getRandomDataAndReader(16)
|
||||
_, err = destBlob.CopyFromURL(ctx, srcBlobURLWithSAS, azblob.Metadata{}, azblob.ModifiedAccessConditions{}, azblob.BlobAccessConditions{}, badMD5)
|
||||
_, err = destBlob.CopyFromURL(ctx, srcBlobURLWithSAS, Metadata{}, ModifiedAccessConditions{}, BlobAccessConditions{}, badMD5)
|
||||
c.Assert(err, chk.NotNil)
|
||||
|
||||
// Edge case 2: Not providing any source MD5 should see the CRC getting returned instead
|
||||
resp, err = destBlob.CopyFromURL(ctx, srcBlobURLWithSAS, azblob.Metadata{}, azblob.ModifiedAccessConditions{}, azblob.BlobAccessConditions{}, nil)
|
||||
resp, err = destBlob.CopyFromURL(ctx, srcBlobURLWithSAS, Metadata{}, ModifiedAccessConditions{}, BlobAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 202)
|
||||
c.Assert(resp.XMsContentCrc64(), chk.Not(chk.Equals), "")
|
||||
|
@ -229,12 +231,12 @@ func (s *aztestsSuite) TestBlobSASQueryParamOverrideResponseHeaders(c *chk.C) {
|
|||
ctx := context.Background() // Use default Background context
|
||||
blob := container.NewBlockBlobURL(generateBlobName())
|
||||
|
||||
uploadResp, err := blob.Upload(ctx, r, azblob.BlobHTTPHeaders{}, azblob.Metadata{}, azblob.BlobAccessConditions{})
|
||||
uploadResp, err := blob.Upload(ctx, r, BlobHTTPHeaders{}, Metadata{}, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(uploadResp.Response().StatusCode, chk.Equals, 201)
|
||||
|
||||
// Get blob URL with SAS.
|
||||
blobParts := azblob.NewBlobURLParts(blob.URL())
|
||||
blobParts := NewBlobURLParts(blob.URL())
|
||||
|
||||
cacheControlVal := "cache-control-override"
|
||||
contentDispositionVal := "content-disposition-override"
|
||||
|
@ -242,12 +244,12 @@ func (s *aztestsSuite) TestBlobSASQueryParamOverrideResponseHeaders(c *chk.C) {
|
|||
contentLanguageVal := "content-language-override"
|
||||
contentTypeVal := "content-type-override"
|
||||
|
||||
blobParts.SAS, err = azblob.BlobSASSignatureValues{
|
||||
Protocol: azblob.SASProtocolHTTPS, // Users MUST use HTTPS (not HTTP)
|
||||
blobParts.SAS, err = BlobSASSignatureValues{
|
||||
Protocol: SASProtocolHTTPS, // Users MUST use HTTPS (not HTTP)
|
||||
ExpiryTime: time.Now().UTC().Add(48 * time.Hour), // 48-hours before expiration
|
||||
ContainerName: blobParts.ContainerName,
|
||||
BlobName: blobParts.BlobName,
|
||||
Permissions: azblob.BlobSASPermissions{Read: true}.String(),
|
||||
Permissions: BlobSASPermissions{Read: true}.String(),
|
||||
CacheControl: cacheControlVal,
|
||||
ContentDisposition: contentDispositionVal,
|
||||
ContentEncoding: contentEncodingVal,
|
||||
|
@ -258,9 +260,9 @@ func (s *aztestsSuite) TestBlobSASQueryParamOverrideResponseHeaders(c *chk.C) {
|
|||
c.Fatal(err)
|
||||
}
|
||||
|
||||
blobURL := azblob.NewBlobURL(blobParts.URL(), azblob.NewPipeline(azblob.NewAnonymousCredential(), azblob.PipelineOptions{}))
|
||||
blobURL := NewBlobURL(blobParts.URL(), NewPipeline(NewAnonymousCredential(), PipelineOptions{}))
|
||||
|
||||
gResp, err := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
gResp, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(gResp.CacheControl(), chk.Equals, cacheControlVal)
|
||||
c.Assert(gResp.ContentDisposition(), chk.Equals, contentDispositionVal)
|
||||
|
@ -280,7 +282,7 @@ func (s *aztestsSuite) TestStageBlockWithMD5(c *chk.C) {
|
|||
// test put block with valid MD5 value
|
||||
readerToBody, body := getRandomDataAndReader(1024)
|
||||
md5Value := md5.Sum(body)
|
||||
putResp, err := blob.StageBlock(context.Background(), blockID, readerToBody, azblob.LeaseAccessConditions{}, md5Value[:])
|
||||
putResp, err := blob.StageBlock(context.Background(), blockID, readerToBody, LeaseAccessConditions{}, md5Value[:])
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(putResp.Response().StatusCode, chk.Equals, 201)
|
||||
c.Assert(putResp.ContentMD5(), chk.DeepEquals, md5Value[:])
|
||||
|
@ -291,8 +293,8 @@ func (s *aztestsSuite) TestStageBlockWithMD5(c *chk.C) {
|
|||
// test put block with bad MD5 value
|
||||
readerToBody, body = getRandomDataAndReader(1024)
|
||||
_, badMD5 := getRandomDataAndReader(16)
|
||||
putResp, err = blob.StageBlock(context.Background(), blockID, readerToBody, azblob.LeaseAccessConditions{}, badMD5[:])
|
||||
validateStorageError(c, err, azblob.ServiceCodeMd5Mismatch)
|
||||
putResp, err = blob.StageBlock(context.Background(), blockID, readerToBody, LeaseAccessConditions{}, badMD5[:])
|
||||
validateStorageError(c, err, ServiceCodeMd5Mismatch)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobPutBlobNonEmptyBody(c *chk.C) {
|
||||
|
@ -301,10 +303,10 @@ func (s *aztestsSuite) TestBlobPutBlobNonEmptyBody(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.Upload(ctx, strings.NewReader(blockBlobDefaultData), azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.Upload(ctx, strings.NewReader(blockBlobDefaultData), BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blobURL.Download(ctx, 0, 0, azblob.BlobAccessConditions{}, false)
|
||||
resp, err := blobURL.Download(ctx, 0, 0, BlobAccessConditions{}, false)
|
||||
c.Assert(err, chk.IsNil)
|
||||
data, err := ioutil.ReadAll(resp.Response().Body)
|
||||
c.Assert(string(data), chk.Equals, blockBlobDefaultData)
|
||||
|
@ -316,10 +318,10 @@ func (s *aztestsSuite) TestBlobPutBlobHTTPHeaders(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.Upload(ctx, bytes.NewReader(nil), basicHeaders, nil, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.Upload(ctx, bytes.NewReader(nil), basicHeaders, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
h := resp.NewHTTPHeaders()
|
||||
h.ContentMD5 = nil // the service generates a MD5 value, omit before comparing
|
||||
|
@ -332,10 +334,10 @@ func (s *aztestsSuite) TestBlobPutBlobMetadataNotEmpty(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.Upload(ctx, bytes.NewReader(nil), azblob.BlobHTTPHeaders{}, basicMetadata, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.Upload(ctx, bytes.NewReader(nil), BlobHTTPHeaders{}, basicMetadata, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
|
||||
}
|
||||
|
@ -346,10 +348,10 @@ func (s *aztestsSuite) TestBlobPutBlobMetadataEmpty(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.Upload(ctx, bytes.NewReader(nil), azblob.BlobHTTPHeaders{}, azblob.Metadata{}, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.Upload(ctx, bytes.NewReader(nil), BlobHTTPHeaders{}, Metadata{}, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.NewMetadata(), chk.HasLen, 0)
|
||||
}
|
||||
|
@ -360,7 +362,7 @@ func (s *aztestsSuite) TestBlobPutBlobMetadataInvalid(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.Upload(ctx, nil, azblob.BlobHTTPHeaders{}, azblob.Metadata{"In valid!": "bar"}, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.Upload(ctx, nil, BlobHTTPHeaders{}, Metadata{"In valid!": "bar"}, BlobAccessConditions{})
|
||||
c.Assert(strings.Contains(err.Error(), validationErrorSubstring), chk.Equals, true)
|
||||
}
|
||||
|
||||
|
@ -372,8 +374,8 @@ func (s *aztestsSuite) TestBlobPutBlobIfModifiedSinceTrue(c *chk.C) {
|
|||
|
||||
currentTime := getRelativeTimeGMT(-10)
|
||||
|
||||
_, err := blobURL.Upload(ctx, bytes.NewReader(nil), azblob.BlobHTTPHeaders{}, nil,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
_, err := blobURL.Upload(ctx, bytes.NewReader(nil), BlobHTTPHeaders{}, nil,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateUpload(c, blobURL)
|
||||
|
@ -387,9 +389,9 @@ func (s *aztestsSuite) TestBlobPutBlobIfModifiedSinceFalse(c *chk.C) {
|
|||
|
||||
currentTime := getRelativeTimeGMT(10)
|
||||
|
||||
_, err := blobURL.Upload(ctx, bytes.NewReader(nil), azblob.BlobHTTPHeaders{}, nil,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
_, err := blobURL.Upload(ctx, bytes.NewReader(nil), BlobHTTPHeaders{}, nil,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobPutBlobIfUnmodifiedSinceTrue(c *chk.C) {
|
||||
|
@ -400,8 +402,8 @@ func (s *aztestsSuite) TestBlobPutBlobIfUnmodifiedSinceTrue(c *chk.C) {
|
|||
|
||||
currentTime := getRelativeTimeGMT(10)
|
||||
|
||||
_, err := blobURL.Upload(ctx, bytes.NewReader(nil), azblob.BlobHTTPHeaders{}, nil,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
_, err := blobURL.Upload(ctx, bytes.NewReader(nil), BlobHTTPHeaders{}, nil,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateUpload(c, blobURL)
|
||||
|
@ -415,9 +417,9 @@ func (s *aztestsSuite) TestBlobPutBlobIfUnmodifiedSinceFalse(c *chk.C) {
|
|||
|
||||
currentTime := getRelativeTimeGMT(-10)
|
||||
|
||||
_, err := blobURL.Upload(ctx, bytes.NewReader(nil), azblob.BlobHTTPHeaders{}, nil,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
_, err := blobURL.Upload(ctx, bytes.NewReader(nil), BlobHTTPHeaders{}, nil,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobPutBlobIfMatchTrue(c *chk.C) {
|
||||
|
@ -426,11 +428,11 @@ func (s *aztestsSuite) TestBlobPutBlobIfMatchTrue(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := createNewBlockBlob(c, containerURL)
|
||||
|
||||
resp, err := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
_, err = blobURL.Upload(ctx, bytes.NewReader(nil), azblob.BlobHTTPHeaders{}, nil,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfMatch: resp.ETag()}})
|
||||
_, err = blobURL.Upload(ctx, bytes.NewReader(nil), BlobHTTPHeaders{}, nil,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: resp.ETag()}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateUpload(c, blobURL)
|
||||
|
@ -442,12 +444,12 @@ func (s *aztestsSuite) TestBlobPutBlobIfMatchFalse(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := createNewBlockBlob(c, containerURL)
|
||||
|
||||
_, err := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
_, err = blobURL.Upload(ctx, bytes.NewReader(nil), azblob.BlobHTTPHeaders{}, nil,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfMatch: azblob.ETag("garbage")}})
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
_, err = blobURL.Upload(ctx, bytes.NewReader(nil), BlobHTTPHeaders{}, nil,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: ETag("garbage")}})
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobPutBlobIfNoneMatchTrue(c *chk.C) {
|
||||
|
@ -456,11 +458,11 @@ func (s *aztestsSuite) TestBlobPutBlobIfNoneMatchTrue(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := createNewBlockBlob(c, containerURL)
|
||||
|
||||
_, err := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
_, err = blobURL.Upload(ctx, bytes.NewReader(nil), azblob.BlobHTTPHeaders{}, nil,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfNoneMatch: azblob.ETag("garbage")}})
|
||||
_, err = blobURL.Upload(ctx, bytes.NewReader(nil), BlobHTTPHeaders{}, nil,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: ETag("garbage")}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateUpload(c, blobURL)
|
||||
|
@ -472,12 +474,20 @@ func (s *aztestsSuite) TestBlobPutBlobIfNoneMatchFalse(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := createNewBlockBlob(c, containerURL)
|
||||
|
||||
resp, err := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
_, err = blobURL.Upload(ctx, bytes.NewReader(nil), azblob.BlobHTTPHeaders{}, nil,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfNoneMatch: resp.ETag()}})
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
_, err = blobURL.Upload(ctx, bytes.NewReader(nil), BlobHTTPHeaders{}, nil,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: resp.ETag()}})
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
var blockID string // a single blockID used in tests when only a single ID is needed
|
||||
|
||||
func init() {
|
||||
u := [64]byte{}
|
||||
binary.BigEndian.PutUint32((u[len(guuid.UUID{}):]), math.MaxUint32)
|
||||
blockID = base64.StdEncoding.EncodeToString(u[:])
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobGetBlockListNone(c *chk.C) {
|
||||
|
@ -486,10 +496,10 @@ func (s *aztestsSuite) TestBlobGetBlockListNone(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.StageBlock(ctx, azblob.BlockID{0}.ToBase64(), strings.NewReader(blockBlobDefaultData), azblob.LeaseAccessConditions{}, nil)
|
||||
_, err := blobURL.StageBlock(ctx, blockID, strings.NewReader(blockBlobDefaultData), LeaseAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blobURL.GetBlockList(ctx, azblob.BlockListNone, azblob.LeaseAccessConditions{})
|
||||
resp, err := blobURL.GetBlockList(ctx, BlockListNone, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.CommittedBlocks, chk.HasLen, 0)
|
||||
c.Assert(resp.UncommittedBlocks, chk.HasLen, 0) // Not specifying a block list type should default to only returning committed blocks
|
||||
|
@ -501,10 +511,10 @@ func (s *aztestsSuite) TestBlobGetBlockListUncommitted(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.StageBlock(ctx, azblob.BlockID{0}.ToBase64(), strings.NewReader(blockBlobDefaultData), azblob.LeaseAccessConditions{}, nil)
|
||||
_, err := blobURL.StageBlock(ctx, blockID, strings.NewReader(blockBlobDefaultData), LeaseAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blobURL.GetBlockList(ctx, azblob.BlockListUncommitted, azblob.LeaseAccessConditions{})
|
||||
resp, err := blobURL.GetBlockList(ctx, BlockListUncommitted, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.CommittedBlocks, chk.HasLen, 0)
|
||||
c.Assert(resp.UncommittedBlocks, chk.HasLen, 1)
|
||||
|
@ -516,12 +526,12 @@ func (s *aztestsSuite) TestBlobGetBlockListCommitted(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.StageBlock(ctx, azblob.BlockID{0}.ToBase64(), strings.NewReader(blockBlobDefaultData), azblob.LeaseAccessConditions{}, nil)
|
||||
_, err := blobURL.StageBlock(ctx, blockID, strings.NewReader(blockBlobDefaultData), LeaseAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{azblob.BlockID{0}.ToBase64()}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{blockID}, BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
|
||||
resp, err := blobURL.GetBlockList(ctx, azblob.BlockListCommitted, azblob.LeaseAccessConditions{})
|
||||
resp, err := blobURL.GetBlockList(ctx, BlockListCommitted, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.CommittedBlocks, chk.HasLen, 1)
|
||||
c.Assert(resp.UncommittedBlocks, chk.HasLen, 0)
|
||||
|
@ -533,10 +543,10 @@ func (s *aztestsSuite) TestBlobGetBlockListCommittedEmpty(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.StageBlock(ctx, azblob.BlockID{0}.ToBase64(), strings.NewReader(blockBlobDefaultData), azblob.LeaseAccessConditions{}, nil)
|
||||
_, err := blobURL.StageBlock(ctx, blockID, strings.NewReader(blockBlobDefaultData), LeaseAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blobURL.GetBlockList(ctx, azblob.BlockListCommitted, azblob.LeaseAccessConditions{})
|
||||
resp, err := blobURL.GetBlockList(ctx, BlockListCommitted, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.CommittedBlocks, chk.HasLen, 0)
|
||||
c.Assert(resp.UncommittedBlocks, chk.HasLen, 0)
|
||||
|
@ -548,8 +558,8 @@ func (s *aztestsSuite) TestBlobGetBlockListBothEmpty(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.GetBlockList(ctx, azblob.BlockListAll, azblob.LeaseAccessConditions{})
|
||||
validateStorageError(c, err, azblob.ServiceCodeBlobNotFound)
|
||||
_, err := blobURL.GetBlockList(ctx, BlockListAll, LeaseAccessConditions{})
|
||||
validateStorageError(c, err, ServiceCodeBlobNotFound)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobGetBlockListBothNotEmpty(c *chk.C) {
|
||||
|
@ -558,26 +568,28 @@ func (s *aztestsSuite) TestBlobGetBlockListBothNotEmpty(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
id := newID()
|
||||
|
||||
// Put and commit two blocks
|
||||
_, err := blobURL.StageBlock(ctx, azblob.BlockID{0}.ToBase64(), strings.NewReader(blockBlobDefaultData), azblob.LeaseAccessConditions{}, nil)
|
||||
_, err := blobURL.StageBlock(ctx, id.next(), strings.NewReader(blockBlobDefaultData), LeaseAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
_, err = blobURL.StageBlock(ctx, azblob.BlockID{1}.ToBase64(), strings.NewReader(blockBlobDefaultData), azblob.LeaseAccessConditions{}, nil)
|
||||
_, err = blobURL.StageBlock(ctx, id.next(), strings.NewReader(blockBlobDefaultData), LeaseAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{azblob.BlockID{1}.ToBase64(), azblob.BlockID{0}.ToBase64()}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
_, err = blobURL.CommitBlockList(ctx, id.issued(), BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
// Put two uncommitted blocks
|
||||
_, err = blobURL.StageBlock(ctx, azblob.BlockID{3}.ToBase64(), strings.NewReader(blockBlobDefaultData), azblob.LeaseAccessConditions{}, nil)
|
||||
_, err = blobURL.StageBlock(ctx, id.next(), strings.NewReader(blockBlobDefaultData), LeaseAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
_, err = blobURL.StageBlock(ctx, azblob.BlockID{2}.ToBase64(), strings.NewReader(blockBlobDefaultData), azblob.LeaseAccessConditions{}, nil)
|
||||
_, err = blobURL.StageBlock(ctx, id.next(), strings.NewReader(blockBlobDefaultData), LeaseAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blobURL.GetBlockList(ctx, azblob.BlockListAll, azblob.LeaseAccessConditions{})
|
||||
resp, err := blobURL.GetBlockList(ctx, BlockListAll, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.CommittedBlocks[0].Name, chk.Equals, azblob.BlockID{1}.ToBase64())
|
||||
c.Assert(resp.CommittedBlocks[1].Name, chk.Equals, azblob.BlockID{0}.ToBase64()) // Committed blocks are returned in the order they are committed (in the commit list)
|
||||
c.Assert(resp.UncommittedBlocks[0].Name, chk.Equals, azblob.BlockID{2}.ToBase64()) // Uncommitted blocks are returned in alphabetical order
|
||||
c.Assert(resp.UncommittedBlocks[1].Name, chk.Equals, azblob.BlockID{3}.ToBase64())
|
||||
c.Assert(resp.CommittedBlocks[0].Name, chk.Equals, id.issued()[0])
|
||||
c.Assert(resp.CommittedBlocks[1].Name, chk.Equals, id.issued()[1]) // Committed blocks are returned in the order they are committed (in the commit list)
|
||||
c.Assert(resp.UncommittedBlocks[0].Name, chk.Equals, id.issued()[2]) // Uncommitted blocks are returned in alphabetical order
|
||||
c.Assert(resp.UncommittedBlocks[1].Name, chk.Equals, id.issued()[3])
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobGetBlockListInvalidType(c *chk.C) {
|
||||
|
@ -586,11 +598,11 @@ func (s *aztestsSuite) TestBlobGetBlockListInvalidType(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.StageBlock(ctx, azblob.BlockID{0}.ToBase64(), strings.NewReader(blockBlobDefaultData), azblob.LeaseAccessConditions{}, nil)
|
||||
_, err := blobURL.StageBlock(ctx, blockID, strings.NewReader(blockBlobDefaultData), LeaseAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
_, err = blobURL.GetBlockList(ctx, azblob.BlockListType("garbage"), azblob.LeaseAccessConditions{})
|
||||
validateStorageError(c, err, azblob.ServiceCodeInvalidQueryParameterValue)
|
||||
_, err = blobURL.GetBlockList(ctx, BlockListType("garbage"), LeaseAccessConditions{})
|
||||
validateStorageError(c, err, ServiceCodeInvalidQueryParameterValue)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobGetBlockListSnapshot(c *chk.C) {
|
||||
|
@ -599,16 +611,16 @@ func (s *aztestsSuite) TestBlobGetBlockListSnapshot(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.StageBlock(ctx, azblob.BlockID{0}.ToBase64(), strings.NewReader(blockBlobDefaultData), azblob.LeaseAccessConditions{}, nil)
|
||||
_, err := blobURL.StageBlock(ctx, blockID, strings.NewReader(blockBlobDefaultData), LeaseAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{azblob.BlockID{0}.ToBase64()}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{blockID}, BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blobURL.CreateSnapshot(ctx, nil, azblob.BlobAccessConditions{})
|
||||
resp, err := blobURL.CreateSnapshot(ctx, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
snapshotURL := blobURL.WithSnapshot(resp.Snapshot())
|
||||
|
||||
resp2, err := snapshotURL.GetBlockList(ctx, azblob.BlockListAll, azblob.LeaseAccessConditions{})
|
||||
resp2, err := snapshotURL.GetBlockList(ctx, BlockListAll, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp2.CommittedBlocks, chk.HasLen, 1)
|
||||
}
|
||||
|
@ -619,8 +631,8 @@ func (s *aztestsSuite) TestBlobPutBlockIDInvalidCharacters(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.StageBlock(ctx, "!!", strings.NewReader(blockBlobDefaultData), azblob.LeaseAccessConditions{}, nil)
|
||||
validateStorageError(c, err, azblob.ServiceCodeInvalidQueryParameterValue)
|
||||
_, err := blobURL.StageBlock(ctx, "!!", strings.NewReader(blockBlobDefaultData), LeaseAccessConditions{}, nil)
|
||||
validateStorageError(c, err, ServiceCodeInvalidQueryParameterValue)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobPutBlockIDInvalidLength(c *chk.C) {
|
||||
|
@ -629,10 +641,10 @@ func (s *aztestsSuite) TestBlobPutBlockIDInvalidLength(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.StageBlock(ctx, azblob.BlockID{0}.ToBase64(), strings.NewReader(blockBlobDefaultData), azblob.LeaseAccessConditions{}, nil)
|
||||
_, err := blobURL.StageBlock(ctx, blockID, strings.NewReader(blockBlobDefaultData), LeaseAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
_, err = blobURL.StageBlock(ctx, "00000000", strings.NewReader(blockBlobDefaultData), azblob.LeaseAccessConditions{}, nil)
|
||||
validateStorageError(c, err, azblob.ServiceCodeInvalidBlobOrBlock)
|
||||
_, err = blobURL.StageBlock(ctx, "00000000", strings.NewReader(blockBlobDefaultData), LeaseAccessConditions{}, nil)
|
||||
validateStorageError(c, err, ServiceCodeInvalidBlobOrBlock)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobPutBlockEmptyBody(c *chk.C) {
|
||||
|
@ -641,36 +653,36 @@ func (s *aztestsSuite) TestBlobPutBlockEmptyBody(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := getBlockBlobURL(c, containerURL)
|
||||
|
||||
_, err := blobURL.StageBlock(ctx, azblob.BlockID{0}.ToBase64(), strings.NewReader(""), azblob.LeaseAccessConditions{}, nil)
|
||||
validateStorageError(c, err, azblob.ServiceCodeInvalidHeaderValue)
|
||||
_, err := blobURL.StageBlock(ctx, blockID, strings.NewReader(""), LeaseAccessConditions{}, nil)
|
||||
validateStorageError(c, err, ServiceCodeInvalidHeaderValue)
|
||||
}
|
||||
|
||||
func setupPutBlockListTest(c *chk.C) (containerURL azblob.ContainerURL, blobURL azblob.BlockBlobURL, id string) {
|
||||
func setupPutBlockListTest(c *chk.C) (containerURL ContainerURL, blobURL BlockBlobURL, id string) {
|
||||
bsu := getBSU()
|
||||
containerURL, _ = createNewContainer(c, bsu)
|
||||
blobURL, _ = getBlockBlobURL(c, containerURL)
|
||||
id = azblob.BlockID{0}.ToBase64()
|
||||
_, err := blobURL.StageBlock(ctx, id, strings.NewReader(blockBlobDefaultData), azblob.LeaseAccessConditions{}, nil)
|
||||
|
||||
_, err := blobURL.StageBlock(ctx, blockID, strings.NewReader(blockBlobDefaultData), LeaseAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
return
|
||||
return containerURL, blobURL, blockID
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobPutBlockListInvalidID(c *chk.C) {
|
||||
containerURL, blobURL, id := setupPutBlockListTest(c)
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id[:2]}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
validateStorageError(c, err, azblob.ServiceCodeInvalidBlockID)
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id[:2]}, BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
validateStorageError(c, err, ServiceCodeInvalidBlockID)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobPutBlockListDuplicateBlocks(c *chk.C) {
|
||||
containerURL, blobURL, id := setupPutBlockListTest(c)
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id, id}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id, id}, BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blobURL.GetBlockList(ctx, azblob.BlockListAll, azblob.LeaseAccessConditions{})
|
||||
resp, err := blobURL.GetBlockList(ctx, BlockListAll, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.CommittedBlocks, chk.HasLen, 2)
|
||||
}
|
||||
|
@ -679,10 +691,10 @@ func (s *aztestsSuite) TestBlobPutBlockListEmptyList(c *chk.C) {
|
|||
containerURL, blobURL, _ := setupPutBlockListTest(c)
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{}, azblob.BlobHTTPHeaders{}, azblob.Metadata{}, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{}, BlobHTTPHeaders{}, Metadata{}, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blobURL.GetBlockList(ctx, azblob.BlockListAll, azblob.LeaseAccessConditions{})
|
||||
resp, err := blobURL.GetBlockList(ctx, BlockListAll, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.CommittedBlocks, chk.HasLen, 0)
|
||||
}
|
||||
|
@ -691,10 +703,10 @@ func (s *aztestsSuite) TestBlobPutBlockListMetadataEmpty(c *chk.C) {
|
|||
containerURL, blobURL, id := setupPutBlockListTest(c)
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, azblob.Metadata{}, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, Metadata{}, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.NewMetadata(), chk.HasLen, 0)
|
||||
}
|
||||
|
@ -703,10 +715,10 @@ func (s *aztestsSuite) TestBlobPutBlockListMetadataNonEmpty(c *chk.C) {
|
|||
containerURL, blobURL, id := setupPutBlockListTest(c)
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, basicMetadata, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, basicMetadata, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
|
||||
}
|
||||
|
@ -715,10 +727,10 @@ func (s *aztestsSuite) TestBlobPutBlockListHTTPHeaders(c *chk.C) {
|
|||
containerURL, blobURL, id := setupPutBlockListTest(c)
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, basicHeaders, nil, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, basicHeaders, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, _ := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
resp, _ := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
h := resp.NewHTTPHeaders()
|
||||
c.Assert(h, chk.DeepEquals, basicHeaders)
|
||||
}
|
||||
|
@ -727,19 +739,19 @@ func (s *aztestsSuite) TestBlobPutBlockListHTTPHeadersEmpty(c *chk.C) {
|
|||
containerURL, blobURL, id := setupPutBlockListTest(c)
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{ContentDisposition: "my_disposition"}, nil, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{ContentDisposition: "my_disposition"}, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blobURL.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
resp, err := blobURL.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.ContentDisposition(), chk.Equals, "")
|
||||
}
|
||||
|
||||
func validateBlobCommitted(c *chk.C, blobURL azblob.BlockBlobURL) {
|
||||
resp, err := blobURL.GetBlockList(ctx, azblob.BlockListAll, azblob.LeaseAccessConditions{})
|
||||
func validateBlobCommitted(c *chk.C, blobURL BlockBlobURL) {
|
||||
resp, err := blobURL.GetBlockList(ctx, BlockListAll, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.CommittedBlocks, chk.HasLen, 1)
|
||||
}
|
||||
|
@ -747,13 +759,13 @@ func validateBlobCommitted(c *chk.C, blobURL azblob.BlockBlobURL) {
|
|||
func (s *aztestsSuite) TestBlobPutBlockListIfModifiedSinceTrue(c *chk.C) {
|
||||
containerURL, blobURL, id := setupPutBlockListTest(c)
|
||||
defer deleteContainer(c, containerURL)
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{}) // The blob must actually exist to have a modifed time
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, nil, BlobAccessConditions{}) // The blob must actually exist to have a modifed time
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
currentTime := getRelativeTimeGMT(-10)
|
||||
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, nil,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, nil,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateBlobCommitted(c, blobURL)
|
||||
|
@ -765,21 +777,21 @@ func (s *aztestsSuite) TestBlobPutBlockListIfModifiedSinceFalse(c *chk.C) {
|
|||
|
||||
currentTime := getRelativeTimeGMT(10)
|
||||
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, nil,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, nil,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobPutBlockListIfUnmodifiedSinceTrue(c *chk.C) {
|
||||
containerURL, blobURL, id := setupPutBlockListTest(c)
|
||||
defer deleteContainer(c, containerURL)
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{}) // The blob must actually exist to have a modifed time
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, nil, BlobAccessConditions{}) // The blob must actually exist to have a modifed time
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
currentTime := getRelativeTimeGMT(10)
|
||||
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, nil,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, nil,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateBlobCommitted(c, blobURL)
|
||||
|
@ -787,25 +799,25 @@ func (s *aztestsSuite) TestBlobPutBlockListIfUnmodifiedSinceTrue(c *chk.C) {
|
|||
|
||||
func (s *aztestsSuite) TestBlobPutBlockListIfUnmodifiedSinceFalse(c *chk.C) {
|
||||
containerURL, blobURL, id := setupPutBlockListTest(c)
|
||||
blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{}) // The blob must actually exist to have a modifed time
|
||||
blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, nil, BlobAccessConditions{}) // The blob must actually exist to have a modifed time
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
currentTime := getRelativeTimeGMT(-10)
|
||||
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, nil,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, nil,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobPutBlockListIfMatchTrue(c *chk.C) {
|
||||
containerURL, blobURL, id := setupPutBlockListTest(c)
|
||||
defer deleteContainer(c, containerURL)
|
||||
resp, err := blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{}) // The blob must actually exist to have a modifed time
|
||||
resp, err := blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, nil, BlobAccessConditions{}) // The blob must actually exist to have a modifed time
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, nil,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfMatch: resp.ETag()}})
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, nil,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: resp.ETag()}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateBlobCommitted(c, blobURL)
|
||||
|
@ -814,23 +826,23 @@ func (s *aztestsSuite) TestBlobPutBlockListIfMatchTrue(c *chk.C) {
|
|||
func (s *aztestsSuite) TestBlobPutBlockListIfMatchFalse(c *chk.C) {
|
||||
containerURL, blobURL, id := setupPutBlockListTest(c)
|
||||
defer deleteContainer(c, containerURL)
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{}) // The blob must actually exist to have a modifed time
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, nil, BlobAccessConditions{}) // The blob must actually exist to have a modifed time
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, nil,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfMatch: azblob.ETag("garbage")}})
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, nil,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: ETag("garbage")}})
|
||||
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobPutBlockListIfNoneMatchTrue(c *chk.C) {
|
||||
containerURL, blobURL, id := setupPutBlockListTest(c)
|
||||
defer deleteContainer(c, containerURL)
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{}) // The blob must actually exist to have a modifed time
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, nil, BlobAccessConditions{}) // The blob must actually exist to have a modifed time
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, nil,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfNoneMatch: azblob.ETag("garbage")}})
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, nil,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: ETag("garbage")}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateBlobCommitted(c, blobURL)
|
||||
|
@ -839,22 +851,22 @@ func (s *aztestsSuite) TestBlobPutBlockListIfNoneMatchTrue(c *chk.C) {
|
|||
func (s *aztestsSuite) TestBlobPutBlockListIfNoneMatchFalse(c *chk.C) {
|
||||
containerURL, blobURL, id := setupPutBlockListTest(c)
|
||||
defer deleteContainer(c, containerURL)
|
||||
resp, err := blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{}) // The blob must actually exist to have a modifed time
|
||||
resp, err := blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, nil, BlobAccessConditions{}) // The blob must actually exist to have a modifed time
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, nil,
|
||||
azblob.BlobAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfNoneMatch: resp.ETag()}})
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, nil,
|
||||
BlobAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfNoneMatch: resp.ETag()}})
|
||||
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestBlobPutBlockListValidateData(c *chk.C) {
|
||||
containerURL, blobURL, id := setupPutBlockListTest(c)
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
|
||||
resp, err := blobURL.Download(ctx, 0, 0, azblob.BlobAccessConditions{}, false)
|
||||
resp, err := blobURL.Download(ctx, 0, 0, BlobAccessConditions{}, false)
|
||||
c.Assert(err, chk.IsNil)
|
||||
data, _ := ioutil.ReadAll(resp.Response().Body)
|
||||
c.Assert(string(data), chk.Equals, blockBlobDefaultData)
|
||||
|
@ -864,22 +876,22 @@ func (s *aztestsSuite) TestBlobPutBlockListModifyBlob(c *chk.C) {
|
|||
containerURL, blobURL, id := setupPutBlockListTest(c)
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.CommitBlockList(ctx, []string{id}, BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
_, err = blobURL.StageBlock(ctx, "0001", bytes.NewReader([]byte("new data")), azblob.LeaseAccessConditions{}, nil)
|
||||
_, err = blobURL.StageBlock(ctx, "0001", bytes.NewReader([]byte("new data")), LeaseAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
_, err = blobURL.StageBlock(ctx, "0010", bytes.NewReader([]byte("new data")), azblob.LeaseAccessConditions{}, nil)
|
||||
_, err = blobURL.StageBlock(ctx, "0010", bytes.NewReader([]byte("new data")), LeaseAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
_, err = blobURL.StageBlock(ctx, "0011", bytes.NewReader([]byte("new data")), azblob.LeaseAccessConditions{}, nil)
|
||||
_, err = blobURL.StageBlock(ctx, "0011", bytes.NewReader([]byte("new data")), LeaseAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
_, err = blobURL.StageBlock(ctx, "0100", bytes.NewReader([]byte("new data")), azblob.LeaseAccessConditions{}, nil)
|
||||
_, err = blobURL.StageBlock(ctx, "0100", bytes.NewReader([]byte("new data")), LeaseAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{"0001", "0011"}, azblob.BlobHTTPHeaders{}, nil, azblob.BlobAccessConditions{})
|
||||
_, err = blobURL.CommitBlockList(ctx, []string{"0001", "0011"}, BlobHTTPHeaders{}, nil, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := blobURL.GetBlockList(ctx, azblob.BlockListAll, azblob.LeaseAccessConditions{})
|
||||
resp, err := blobURL.GetBlockList(ctx, BlockListAll, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.CommittedBlocks, chk.HasLen, 2)
|
||||
c.Assert(resp.CommittedBlocks[0].Name, chk.Equals, "0001")
|
||||
|
|
|
@ -1,22 +1,19 @@
|
|||
package azblob_test
|
||||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"bytes"
|
||||
|
||||
"context"
|
||||
"errors"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-storage-blob-go/azblob"
|
||||
chk "gopkg.in/check.v1" // go get gopkg.in/check.v1
|
||||
)
|
||||
|
||||
func delContainer(c *chk.C, container azblob.ContainerURL) {
|
||||
resp, err := container.Delete(context.Background(), azblob.ContainerAccessConditions{})
|
||||
func delContainer(c *chk.C, container ContainerURL) {
|
||||
resp, err := container.Delete(context.Background(), ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 202)
|
||||
}
|
||||
|
@ -32,7 +29,7 @@ func (s *aztestsSuite) TestNewContainerURLValidName(c *chk.C) {
|
|||
|
||||
func (s *aztestsSuite) TestCreateRootContainerURL(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
testURL := bsu.NewContainerURL(azblob.ContainerNameRoot)
|
||||
testURL := bsu.NewContainerURL(ContainerNameRoot)
|
||||
|
||||
correctURL := "https://" + os.Getenv("ACCOUNT_NAME") + ".blob.core.windows.net/$root"
|
||||
temp := testURL.URL()
|
||||
|
@ -44,7 +41,7 @@ func (s *aztestsSuite) TestAccountWithPipeline(c *chk.C) {
|
|||
bsu = bsu.WithPipeline(testPipeline{}) // testPipeline returns an identifying message as an error
|
||||
containerURL := bsu.NewContainerURL("name")
|
||||
|
||||
_, err := containerURL.Create(ctx, azblob.Metadata{}, azblob.PublicAccessBlob)
|
||||
_, err := containerURL.Create(ctx, Metadata{}, PublicAccessBlob)
|
||||
|
||||
c.Assert(err.Error(), chk.Equals, testPipelineMessage)
|
||||
}
|
||||
|
@ -53,18 +50,18 @@ func (s *aztestsSuite) TestContainerCreateInvalidName(c *chk.C) {
|
|||
bsu := getBSU()
|
||||
containerURL := bsu.NewContainerURL("foo bar")
|
||||
|
||||
_, err := containerURL.Create(ctx, azblob.Metadata{}, azblob.PublicAccessBlob)
|
||||
_, err := containerURL.Create(ctx, Metadata{}, PublicAccessBlob)
|
||||
|
||||
validateStorageError(c, err, azblob.ServiceCodeInvalidResourceName)
|
||||
validateStorageError(c, err, ServiceCodeInvalidResourceName)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerCreateEmptyName(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
containerURL := bsu.NewContainerURL("")
|
||||
|
||||
_, err := containerURL.Create(ctx, azblob.Metadata{}, azblob.PublicAccessBlob)
|
||||
_, err := containerURL.Create(ctx, Metadata{}, PublicAccessBlob)
|
||||
|
||||
validateStorageError(c, err, azblob.ServiceCodeInvalidQueryParameterValue)
|
||||
validateStorageError(c, err, ServiceCodeInvalidQueryParameterValue)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerCreateNameCollision(c *chk.C) {
|
||||
|
@ -74,16 +71,16 @@ func (s *aztestsSuite) TestContainerCreateNameCollision(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
|
||||
containerURL = bsu.NewContainerURL(containerName)
|
||||
_, err := containerURL.Create(ctx, azblob.Metadata{}, azblob.PublicAccessBlob)
|
||||
_, err := containerURL.Create(ctx, Metadata{}, PublicAccessBlob)
|
||||
|
||||
validateStorageError(c, err, azblob.ServiceCodeContainerAlreadyExists)
|
||||
validateStorageError(c, err, ServiceCodeContainerAlreadyExists)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerCreateInvalidMetadata(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
containerURL, _ := getContainerURL(c, bsu)
|
||||
|
||||
_, err := containerURL.Create(ctx, azblob.Metadata{"1 foo": "bar"}, azblob.PublicAccessBlob)
|
||||
_, err := containerURL.Create(ctx, Metadata{"1 foo": "bar"}, PublicAccessBlob)
|
||||
|
||||
c.Assert(err, chk.NotNil)
|
||||
c.Assert(strings.Contains(err.Error(), invalidHeaderErrorSubstring), chk.Equals, true)
|
||||
|
@ -93,11 +90,11 @@ func (s *aztestsSuite) TestContainerCreateNilMetadata(c *chk.C) {
|
|||
bsu := getBSU()
|
||||
containerURL, _ := getContainerURL(c, bsu)
|
||||
|
||||
_, err := containerURL.Create(ctx, nil, azblob.PublicAccessBlob)
|
||||
_, err := containerURL.Create(ctx, nil, PublicAccessBlob)
|
||||
defer deleteContainer(c, containerURL)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
response, err := containerURL.GetProperties(ctx, azblob.LeaseAccessConditions{})
|
||||
response, err := containerURL.GetProperties(ctx, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(response.NewMetadata(), chk.HasLen, 0)
|
||||
}
|
||||
|
@ -106,11 +103,11 @@ func (s *aztestsSuite) TestContainerCreateEmptyMetadata(c *chk.C) {
|
|||
bsu := getBSU()
|
||||
containerURL, _ := getContainerURL(c, bsu)
|
||||
|
||||
_, err := containerURL.Create(ctx, azblob.Metadata{}, azblob.PublicAccessBlob)
|
||||
_, err := containerURL.Create(ctx, Metadata{}, PublicAccessBlob)
|
||||
defer deleteContainer(c, containerURL)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
response, err := containerURL.GetProperties(ctx, azblob.LeaseAccessConditions{})
|
||||
response, err := containerURL.GetProperties(ctx, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(response.NewMetadata(), chk.HasLen, 0)
|
||||
}
|
||||
|
@ -122,24 +119,24 @@ func (s *aztestsSuite) TestContainerCreateAccessContainer(c *chk.C) {
|
|||
bsu := getBSU()
|
||||
containerURL, _ := getContainerURL(c, bsu)
|
||||
|
||||
_, err := containerURL.Create(ctx, nil, azblob.PublicAccessContainer)
|
||||
_, err := containerURL.Create(ctx, nil, PublicAccessContainer)
|
||||
defer deleteContainer(c, containerURL)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
blobURL := containerURL.NewBlockBlobURL(blobPrefix)
|
||||
blobURL.Upload(ctx, bytes.NewReader([]byte("Content")), azblob.BlobHTTPHeaders{},
|
||||
basicMetadata, azblob.BlobAccessConditions{})
|
||||
blobURL.Upload(ctx, bytes.NewReader([]byte("Content")), BlobHTTPHeaders{},
|
||||
basicMetadata, BlobAccessConditions{})
|
||||
|
||||
// Anonymous enumeration should be valid with container access
|
||||
containerURL2 := azblob.NewContainerURL(containerURL.URL(), azblob.NewPipeline(azblob.NewAnonymousCredential(), azblob.PipelineOptions{}))
|
||||
response, err := containerURL2.ListBlobsFlatSegment(ctx, azblob.Marker{},
|
||||
azblob.ListBlobsSegmentOptions{})
|
||||
containerURL2 := NewContainerURL(containerURL.URL(), NewPipeline(NewAnonymousCredential(), PipelineOptions{}))
|
||||
response, err := containerURL2.ListBlobsFlatSegment(ctx, Marker{},
|
||||
ListBlobsSegmentOptions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(response.Segment.BlobItems[0].Name, chk.Equals, blobPrefix)
|
||||
|
||||
// Getting blob data anonymously should still be valid with container access
|
||||
blobURL2 := containerURL2.NewBlockBlobURL(blobPrefix)
|
||||
resp, err := blobURL2.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
resp, err := blobURL2.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
|
||||
}
|
||||
|
@ -148,22 +145,22 @@ func (s *aztestsSuite) TestContainerCreateAccessBlob(c *chk.C) {
|
|||
bsu := getBSU()
|
||||
containerURL, _ := getContainerURL(c, bsu)
|
||||
|
||||
_, err := containerURL.Create(ctx, nil, azblob.PublicAccessBlob)
|
||||
_, err := containerURL.Create(ctx, nil, PublicAccessBlob)
|
||||
defer deleteContainer(c, containerURL)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
blobURL := containerURL.NewBlockBlobURL(blobPrefix)
|
||||
blobURL.Upload(ctx, bytes.NewReader([]byte("Content")), azblob.BlobHTTPHeaders{},
|
||||
basicMetadata, azblob.BlobAccessConditions{})
|
||||
blobURL.Upload(ctx, bytes.NewReader([]byte("Content")), BlobHTTPHeaders{},
|
||||
basicMetadata, BlobAccessConditions{})
|
||||
|
||||
// Reference the same container URL but with anonymous credentials
|
||||
containerURL2 := azblob.NewContainerURL(containerURL.URL(), azblob.NewPipeline(azblob.NewAnonymousCredential(), azblob.PipelineOptions{}))
|
||||
_, err = containerURL2.ListBlobsFlatSegment(ctx, azblob.Marker{}, azblob.ListBlobsSegmentOptions{})
|
||||
validateStorageError(c, err, azblob.ServiceCodeResourceNotFound) // Listing blobs is not publicly accessible
|
||||
containerURL2 := NewContainerURL(containerURL.URL(), NewPipeline(NewAnonymousCredential(), PipelineOptions{}))
|
||||
_, err = containerURL2.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{})
|
||||
validateStorageError(c, err, ServiceCodeResourceNotFound) // Listing blobs is not publicly accessible
|
||||
|
||||
// Accessing blob specific data should be public
|
||||
blobURL2 := containerURL2.NewBlockBlobURL(blobPrefix)
|
||||
resp, err := blobURL2.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
resp, err := blobURL2.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
|
||||
}
|
||||
|
@ -172,37 +169,37 @@ func (s *aztestsSuite) TestContainerCreateAccessNone(c *chk.C) {
|
|||
bsu := getBSU()
|
||||
containerURL, _ := getContainerURL(c, bsu)
|
||||
|
||||
_, err := containerURL.Create(ctx, nil, azblob.PublicAccessNone)
|
||||
_, err := containerURL.Create(ctx, nil, PublicAccessNone)
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
blobURL := containerURL.NewBlockBlobURL(blobPrefix)
|
||||
blobURL.Upload(ctx, bytes.NewReader([]byte("Content")), azblob.BlobHTTPHeaders{},
|
||||
basicMetadata, azblob.BlobAccessConditions{})
|
||||
blobURL.Upload(ctx, bytes.NewReader([]byte("Content")), BlobHTTPHeaders{},
|
||||
basicMetadata, BlobAccessConditions{})
|
||||
|
||||
// Reference the same container URL but with anonymous credentials
|
||||
containerURL2 := azblob.NewContainerURL(containerURL.URL(), azblob.NewPipeline(azblob.NewAnonymousCredential(), azblob.PipelineOptions{}))
|
||||
containerURL2 := NewContainerURL(containerURL.URL(), NewPipeline(NewAnonymousCredential(), PipelineOptions{}))
|
||||
// Listing blobs is not public
|
||||
_, err = containerURL2.ListBlobsFlatSegment(ctx, azblob.Marker{}, azblob.ListBlobsSegmentOptions{})
|
||||
validateStorageError(c, err, azblob.ServiceCodeResourceNotFound)
|
||||
_, err = containerURL2.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{})
|
||||
validateStorageError(c, err, ServiceCodeResourceNotFound)
|
||||
|
||||
// Blob data is not public
|
||||
blobURL2 := containerURL2.NewBlockBlobURL(blobPrefix)
|
||||
_, err = blobURL2.GetProperties(ctx, azblob.BlobAccessConditions{})
|
||||
_, err = blobURL2.GetProperties(ctx, BlobAccessConditions{})
|
||||
c.Assert(err, chk.NotNil)
|
||||
serr := err.(azblob.StorageError)
|
||||
serr := err.(StorageError)
|
||||
c.Assert(serr.Response().StatusCode, chk.Equals, 404) // HEAD request does not return a status code
|
||||
}
|
||||
|
||||
func validateContainerDeleted(c *chk.C, containerURL azblob.ContainerURL) {
|
||||
_, err := containerURL.GetAccessPolicy(ctx, azblob.LeaseAccessConditions{})
|
||||
validateStorageError(c, err, azblob.ServiceCodeContainerNotFound)
|
||||
func validateContainerDeleted(c *chk.C, containerURL ContainerURL) {
|
||||
_, err := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
||||
validateStorageError(c, err, ServiceCodeContainerNotFound)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerDelete(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
containerURL, _ := createNewContainer(c, bsu)
|
||||
|
||||
_, err := containerURL.Delete(ctx, azblob.ContainerAccessConditions{})
|
||||
_, err := containerURL.Delete(ctx, ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateContainerDeleted(c, containerURL)
|
||||
|
@ -212,8 +209,8 @@ func (s *aztestsSuite) TestContainerDeleteNonExistant(c *chk.C) {
|
|||
bsu := getBSU()
|
||||
containerURL, _ := getContainerURL(c, bsu)
|
||||
|
||||
_, err := containerURL.Delete(ctx, azblob.ContainerAccessConditions{})
|
||||
validateStorageError(c, err, azblob.ServiceCodeContainerNotFound)
|
||||
_, err := containerURL.Delete(ctx, ContainerAccessConditions{})
|
||||
validateStorageError(c, err, ServiceCodeContainerNotFound)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerDeleteIfModifiedSinceTrue(c *chk.C) {
|
||||
|
@ -222,7 +219,7 @@ func (s *aztestsSuite) TestContainerDeleteIfModifiedSinceTrue(c *chk.C) {
|
|||
containerURL, _ := createNewContainer(c, bsu)
|
||||
|
||||
_, err := containerURL.Delete(ctx,
|
||||
azblob.ContainerAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
validateContainerDeleted(c, containerURL)
|
||||
}
|
||||
|
@ -236,8 +233,8 @@ func (s *aztestsSuite) TestContainerDeleteIfModifiedSinceFalse(c *chk.C) {
|
|||
currentTime := getRelativeTimeGMT(10)
|
||||
|
||||
_, err := containerURL.Delete(ctx,
|
||||
azblob.ContainerAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerDeleteIfUnModifiedSinceTrue(c *chk.C) {
|
||||
|
@ -246,7 +243,7 @@ func (s *aztestsSuite) TestContainerDeleteIfUnModifiedSinceTrue(c *chk.C) {
|
|||
|
||||
currentTime := getRelativeTimeGMT(10)
|
||||
_, err := containerURL.Delete(ctx,
|
||||
azblob.ContainerAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
validateContainerDeleted(c, containerURL)
|
||||
|
@ -261,8 +258,8 @@ func (s *aztestsSuite) TestContainerDeleteIfUnModifiedSinceFalse(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err := containerURL.Delete(ctx,
|
||||
azblob.ContainerAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerAccessConditionsUnsupportedConditions(c *chk.C) {
|
||||
|
@ -272,9 +269,9 @@ func (s *aztestsSuite) TestContainerAccessConditionsUnsupportedConditions(c *chk
|
|||
containerURL, _ := createNewContainer(c, bsu)
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
invalidEtag := azblob.ETag("invalid")
|
||||
invalidEtag := ETag("invalid")
|
||||
_, err := containerURL.SetMetadata(ctx, basicMetadata,
|
||||
azblob.ContainerAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfMatch: invalidEtag}})
|
||||
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfMatch: invalidEtag}})
|
||||
c.Assert(err, chk.Not(chk.Equals), nil)
|
||||
}
|
||||
|
||||
|
@ -284,7 +281,7 @@ func (s *aztestsSuite) TestContainerListBlobsNonexistantPrefix(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
createNewBlockBlob(c, containerURL)
|
||||
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, azblob.Marker{}, azblob.ListBlobsSegmentOptions{Prefix: blobPrefix + blobPrefix})
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{Prefix: blobPrefix + blobPrefix})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Segment.BlobItems, chk.HasLen, 0)
|
||||
|
@ -296,7 +293,7 @@ func (s *aztestsSuite) TestContainerListBlobsSpecificValidPrefix(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
_, blobName := createNewBlockBlob(c, containerURL)
|
||||
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, azblob.Marker{}, azblob.ListBlobsSegmentOptions{Prefix: blobPrefix})
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{Prefix: blobPrefix})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Segment.BlobItems, chk.HasLen, 1)
|
||||
|
@ -312,7 +309,7 @@ func (s *aztestsSuite) TestContainerListBlobsValidDelimiter(c *chk.C) {
|
|||
createBlockBlobWithPrefix(c, containerURL, "b/1")
|
||||
_, blobName := createBlockBlobWithPrefix(c, containerURL, "blob")
|
||||
|
||||
resp, err := containerURL.ListBlobsHierarchySegment(ctx, azblob.Marker{}, "/", azblob.ListBlobsSegmentOptions{})
|
||||
resp, err := containerURL.ListBlobsHierarchySegment(ctx, Marker{}, "/", ListBlobsSegmentOptions{})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(len(resp.Segment.BlobItems), chk.Equals, 1)
|
||||
|
@ -327,7 +324,7 @@ func (s *aztestsSuite) TestContainerListBlobsWithSnapshots(c *chk.C) {
|
|||
containerURL, _ := createNewContainer(c, bsu)
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err := containerURL.ListBlobsHierarchySegment(ctx, azblob.Marker{}, "/", azblob.ListBlobsSegmentOptions{Details: azblob.BlobListingDetails{Snapshots: true}})
|
||||
_, err := containerURL.ListBlobsHierarchySegment(ctx, Marker{}, "/", ListBlobsSegmentOptions{Details: BlobListingDetails{Snapshots: true}})
|
||||
c.Assert(err, chk.Not(chk.Equals), nil)
|
||||
}
|
||||
|
||||
|
@ -340,7 +337,7 @@ func (s *aztestsSuite) TestContainerListBlobsInvalidDelimiter(c *chk.C) {
|
|||
createBlockBlobWithPrefix(c, containerURL, "b/1")
|
||||
createBlockBlobWithPrefix(c, containerURL, "blob")
|
||||
|
||||
resp, err := containerURL.ListBlobsHierarchySegment(ctx, azblob.Marker{}, "^", azblob.ListBlobsSegmentOptions{})
|
||||
resp, err := containerURL.ListBlobsHierarchySegment(ctx, Marker{}, "^", ListBlobsSegmentOptions{})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Segment.BlobItems, chk.HasLen, 4)
|
||||
|
@ -352,10 +349,10 @@ func (s *aztestsSuite) TestContainerListBlobsIncludeTypeMetadata(c *chk.C) {
|
|||
defer deleteContainer(c, container)
|
||||
_, blobNameNoMetadata := createBlockBlobWithPrefix(c, container, "a")
|
||||
blobMetadata, blobNameMetadata := createBlockBlobWithPrefix(c, container, "b")
|
||||
_, err := blobMetadata.SetMetadata(ctx, azblob.Metadata{"field": "value"}, azblob.BlobAccessConditions{})
|
||||
_, err := blobMetadata.SetMetadata(ctx, Metadata{"field": "value"}, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := container.ListBlobsFlatSegment(ctx, azblob.Marker{}, azblob.ListBlobsSegmentOptions{Details: azblob.BlobListingDetails{Metadata: true}})
|
||||
resp, err := container.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{Details: BlobListingDetails{Metadata: true}})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Segment.BlobItems[0].Name, chk.Equals, blobNameNoMetadata)
|
||||
|
@ -369,11 +366,11 @@ func (s *aztestsSuite) TestContainerListBlobsIncludeTypeSnapshots(c *chk.C) {
|
|||
containerURL, _ := createNewContainer(c, bsu)
|
||||
defer deleteContainer(c, containerURL)
|
||||
blob, blobName := createNewBlockBlob(c, containerURL)
|
||||
_, err := blob.CreateSnapshot(ctx, azblob.Metadata{}, azblob.BlobAccessConditions{})
|
||||
_, err := blob.CreateSnapshot(ctx, Metadata{}, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, azblob.Marker{},
|
||||
azblob.ListBlobsSegmentOptions{Details: azblob.BlobListingDetails{Snapshots: true}})
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{},
|
||||
ListBlobsSegmentOptions{Details: BlobListingDetails{Snapshots: true}})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Segment.BlobItems, chk.HasLen, 2)
|
||||
|
@ -389,11 +386,11 @@ func (s *aztestsSuite) TestContainerListBlobsIncludeTypeCopy(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
blobURL, blobName := createNewBlockBlob(c, containerURL)
|
||||
blobCopyURL, blobCopyName := createBlockBlobWithPrefix(c, containerURL, "copy")
|
||||
_, err := blobCopyURL.StartCopyFromURL(ctx, blobURL.URL(), azblob.Metadata{}, azblob.ModifiedAccessConditions{}, azblob.BlobAccessConditions{})
|
||||
_, err := blobCopyURL.StartCopyFromURL(ctx, blobURL.URL(), Metadata{}, ModifiedAccessConditions{}, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, azblob.Marker{},
|
||||
azblob.ListBlobsSegmentOptions{Details: azblob.BlobListingDetails{Copy: true}})
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{},
|
||||
ListBlobsSegmentOptions{Details: BlobListingDetails{Copy: true}})
|
||||
|
||||
// These are sufficient to show that the blob copy was in fact included
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
@ -403,7 +400,7 @@ func (s *aztestsSuite) TestContainerListBlobsIncludeTypeCopy(c *chk.C) {
|
|||
c.Assert(*resp.Segment.BlobItems[0].Properties.ContentLength, chk.Equals, int64(len(blockBlobDefaultData)))
|
||||
temp := blobURL.URL()
|
||||
c.Assert(*resp.Segment.BlobItems[0].Properties.CopySource, chk.Equals, temp.String())
|
||||
c.Assert(resp.Segment.BlobItems[0].Properties.CopyStatus, chk.Equals, azblob.CopyStatusSuccess)
|
||||
c.Assert(resp.Segment.BlobItems[0].Properties.CopyStatus, chk.Equals, CopyStatusSuccess)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerListBlobsIncludeTypeUncommitted(c *chk.C) {
|
||||
|
@ -411,27 +408,27 @@ func (s *aztestsSuite) TestContainerListBlobsIncludeTypeUncommitted(c *chk.C) {
|
|||
containerURL, _ := createNewContainer(c, bsu)
|
||||
defer deleteContainer(c, containerURL)
|
||||
blobURL, blobName := getBlockBlobURL(c, containerURL)
|
||||
_, err := blobURL.StageBlock(ctx, azblob.BlockID{0}.ToBase64(), strings.NewReader(blockBlobDefaultData), azblob.LeaseAccessConditions{}, nil)
|
||||
_, err := blobURL.StageBlock(ctx, blockID, strings.NewReader(blockBlobDefaultData), LeaseAccessConditions{}, nil)
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, azblob.Marker{},
|
||||
azblob.ListBlobsSegmentOptions{Details: azblob.BlobListingDetails{UncommittedBlobs: true}})
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{},
|
||||
ListBlobsSegmentOptions{Details: BlobListingDetails{UncommittedBlobs: true}})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Segment.BlobItems, chk.HasLen, 1)
|
||||
c.Assert(resp.Segment.BlobItems[0].Name, chk.Equals, blobName)
|
||||
}
|
||||
|
||||
func testContainerListBlobsIncludeTypeDeletedImpl(c *chk.C, bsu azblob.ServiceURL) error {
|
||||
func testContainerListBlobsIncludeTypeDeletedImpl(c *chk.C, bsu ServiceURL) error {
|
||||
containerURL, _ := createNewContainer(c, bsu)
|
||||
defer deleteContainer(c, containerURL)
|
||||
blobURL, _ := createNewBlockBlob(c, containerURL)
|
||||
|
||||
_, err := blobURL.Delete(ctx, azblob.DeleteSnapshotsOptionNone, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.Delete(ctx, DeleteSnapshotsOptionNone, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, azblob.Marker{},
|
||||
azblob.ListBlobsSegmentOptions{Details: azblob.BlobListingDetails{Deleted: true}})
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{},
|
||||
ListBlobsSegmentOptions{Details: BlobListingDetails{Deleted: true}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
if len(resp.Segment.BlobItems) != 1 {
|
||||
return errors.New("DeletedBlobNotFound")
|
||||
|
@ -447,22 +444,22 @@ func (s *aztestsSuite) TestContainerListBlobsIncludeTypeDeleted(c *chk.C) {
|
|||
testContainerListBlobsIncludeTypeDeletedImpl, disableSoftDelete)
|
||||
}
|
||||
|
||||
func testContainerListBlobsIncludeMultipleImpl(c *chk.C, bsu azblob.ServiceURL) error {
|
||||
func testContainerListBlobsIncludeMultipleImpl(c *chk.C, bsu ServiceURL) error {
|
||||
containerURL, _ := createNewContainer(c, bsu)
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
blobURL, blobName := createBlockBlobWithPrefix(c, containerURL, "z")
|
||||
_, err := blobURL.CreateSnapshot(ctx, azblob.Metadata{}, azblob.BlobAccessConditions{})
|
||||
_, err := blobURL.CreateSnapshot(ctx, Metadata{}, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
blobURL2, blobName2 := createBlockBlobWithPrefix(c, containerURL, "copy")
|
||||
resp2, err := blobURL2.StartCopyFromURL(ctx, blobURL.URL(), azblob.Metadata{}, azblob.ModifiedAccessConditions{}, azblob.BlobAccessConditions{})
|
||||
resp2, err := blobURL2.StartCopyFromURL(ctx, blobURL.URL(), Metadata{}, ModifiedAccessConditions{}, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
waitForCopy(c, blobURL2, resp2)
|
||||
blobURL3, blobName3 := createBlockBlobWithPrefix(c, containerURL, "deleted")
|
||||
_, err = blobURL3.Delete(ctx, azblob.DeleteSnapshotsOptionNone, azblob.BlobAccessConditions{})
|
||||
_, err = blobURL3.Delete(ctx, DeleteSnapshotsOptionNone, BlobAccessConditions{})
|
||||
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, azblob.Marker{},
|
||||
azblob.ListBlobsSegmentOptions{Details: azblob.BlobListingDetails{Snapshots: true, Copy: true, Deleted: true}})
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{},
|
||||
ListBlobsSegmentOptions{Details: BlobListingDetails{Snapshots: true, Copy: true, Deleted: true}})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
if len(resp.Segment.BlobItems) != 5 { // If there are fewer blobs in the container than there should be, it will be because one was permanently deleted.
|
||||
|
@ -489,7 +486,7 @@ func (s *aztestsSuite) TestContainerListBlobsMaxResultsNegative(c *chk.C) {
|
|||
containerURL, _ := createNewContainer(c, bsu)
|
||||
|
||||
defer deleteContainer(c, containerURL)
|
||||
_, err := containerURL.ListBlobsFlatSegment(ctx, azblob.Marker{}, azblob.ListBlobsSegmentOptions{MaxResults: -2})
|
||||
_, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{MaxResults: -2})
|
||||
c.Assert(err, chk.Not(chk.IsNil))
|
||||
}
|
||||
|
||||
|
@ -499,7 +496,7 @@ func (s *aztestsSuite) TestContainerListBlobsMaxResultsZero(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
createNewBlockBlob(c, containerURL)
|
||||
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, azblob.Marker{}, azblob.ListBlobsSegmentOptions{MaxResults: 0})
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{MaxResults: 0})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Segment.BlobItems, chk.HasLen, 1)
|
||||
|
@ -512,7 +509,7 @@ func (s *aztestsSuite) TestContainerListBlobsMaxResultsInsufficient(c *chk.C) {
|
|||
_, blobName := createBlockBlobWithPrefix(c, containerURL, "a")
|
||||
createBlockBlobWithPrefix(c, containerURL, "b")
|
||||
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, azblob.Marker{}, azblob.ListBlobsSegmentOptions{MaxResults: 1})
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{MaxResults: 1})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Segment.BlobItems, chk.HasLen, 1)
|
||||
|
@ -526,7 +523,7 @@ func (s *aztestsSuite) TestContainerListBlobsMaxResultsExact(c *chk.C) {
|
|||
_, blobName := createBlockBlobWithPrefix(c, containerURL, "a")
|
||||
_, blobName2 := createBlockBlobWithPrefix(c, containerURL, "b")
|
||||
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, azblob.Marker{}, azblob.ListBlobsSegmentOptions{MaxResults: 2})
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{MaxResults: 2})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Segment.BlobItems, chk.HasLen, 2)
|
||||
|
@ -541,7 +538,7 @@ func (s *aztestsSuite) TestContainerListBlobsMaxResultsSufficient(c *chk.C) {
|
|||
_, blobName := createBlockBlobWithPrefix(c, containerURL, "a")
|
||||
_, blobName2 := createBlockBlobWithPrefix(c, containerURL, "b")
|
||||
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, azblob.Marker{}, azblob.ListBlobsSegmentOptions{MaxResults: 3})
|
||||
resp, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{MaxResults: 3})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Segment.BlobItems, chk.HasLen, 2)
|
||||
|
@ -553,7 +550,7 @@ func (s *aztestsSuite) TestContainerListBlobsNonExistentContainer(c *chk.C) {
|
|||
bsu := getBSU()
|
||||
containerURL, _ := getContainerURL(c, bsu)
|
||||
|
||||
_, err := containerURL.ListBlobsFlatSegment(ctx, azblob.Marker{}, azblob.ListBlobsSegmentOptions{})
|
||||
_, err := containerURL.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{})
|
||||
|
||||
c.Assert(err, chk.NotNil)
|
||||
}
|
||||
|
@ -564,7 +561,7 @@ func (s *aztestsSuite) TestContainerWithNewPipeline(c *chk.C) {
|
|||
containerURL, _ := getContainerURL(c, bsu)
|
||||
containerURL = containerURL.WithPipeline(pipeline)
|
||||
|
||||
_, err := containerURL.Create(ctx, azblob.Metadata{}, azblob.PublicAccessBlob)
|
||||
_, err := containerURL.Create(ctx, Metadata{}, PublicAccessBlob)
|
||||
|
||||
c.Assert(err, chk.NotNil)
|
||||
c.Assert(err.Error(), chk.Equals, testPipelineMessage)
|
||||
|
@ -580,29 +577,29 @@ func (s *aztestsSuite) TestContainerGetSetPermissionsMultiplePolicies(c *chk.C)
|
|||
start := generateCurrentTimeWithModerateResolution()
|
||||
expiry := start.Add(5 * time.Minute)
|
||||
expiry2 := start.Add(time.Minute)
|
||||
permissions := []azblob.SignedIdentifier{
|
||||
permissions := []SignedIdentifier{
|
||||
{ID: "0000",
|
||||
AccessPolicy: azblob.AccessPolicy{
|
||||
AccessPolicy: AccessPolicy{
|
||||
Start: start,
|
||||
Expiry: expiry,
|
||||
Permission: azblob.AccessPolicyPermission{Read: true, Write: true}.String(),
|
||||
Permission: AccessPolicyPermission{Read: true, Write: true}.String(),
|
||||
},
|
||||
},
|
||||
{ID: "0001",
|
||||
AccessPolicy: azblob.AccessPolicy{
|
||||
AccessPolicy: AccessPolicy{
|
||||
Start: start,
|
||||
Expiry: expiry2,
|
||||
Permission: azblob.AccessPolicyPermission{Read: true}.String(),
|
||||
Permission: AccessPolicyPermission{Read: true}.String(),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, err := containerURL.SetAccessPolicy(ctx, azblob.PublicAccessNone, permissions,
|
||||
azblob.ContainerAccessConditions{})
|
||||
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessNone, permissions,
|
||||
ContainerAccessConditions{})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := containerURL.GetAccessPolicy(ctx, azblob.LeaseAccessConditions{})
|
||||
resp, err := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Items, chk.DeepEquals, permissions)
|
||||
}
|
||||
|
@ -610,14 +607,14 @@ func (s *aztestsSuite) TestContainerGetSetPermissionsMultiplePolicies(c *chk.C)
|
|||
func (s *aztestsSuite) TestContainerGetPermissionsPublicAccessNotNone(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
containerURL, _ := getContainerURL(c, bsu)
|
||||
containerURL.Create(ctx, nil, azblob.PublicAccessBlob) // We create the container explicitly so we can be sure the access policy is not empty
|
||||
containerURL.Create(ctx, nil, PublicAccessBlob) // We create the container explicitly so we can be sure the access policy is not empty
|
||||
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
resp, err := containerURL.GetAccessPolicy(ctx, azblob.LeaseAccessConditions{})
|
||||
resp, err := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.BlobPublicAccess(), chk.Equals, azblob.PublicAccessBlob)
|
||||
c.Assert(resp.BlobPublicAccess(), chk.Equals, PublicAccessBlob)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerSetPermissionsPublicAccessNone(c *chk.C) {
|
||||
|
@ -629,21 +626,21 @@ func (s *aztestsSuite) TestContainerSetPermissionsPublicAccessNone(c *chk.C) {
|
|||
_, blobName := createNewBlockBlob(c, containerURL)
|
||||
|
||||
// Container is created with PublicAccessBlob, so setting it to None will actually test that it is changed through this method
|
||||
_, err := containerURL.SetAccessPolicy(ctx, azblob.PublicAccessNone, nil, azblob.ContainerAccessConditions{})
|
||||
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessNone, nil, ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
pipeline := azblob.NewPipeline(azblob.NewAnonymousCredential(), azblob.PipelineOptions{})
|
||||
bsu2 := azblob.NewServiceURL(bsu.URL(), pipeline)
|
||||
pipeline := NewPipeline(NewAnonymousCredential(), PipelineOptions{})
|
||||
bsu2 := NewServiceURL(bsu.URL(), pipeline)
|
||||
containerURL2 := bsu2.NewContainerURL(containerName)
|
||||
blobURL2 := containerURL2.NewBlockBlobURL(blobName)
|
||||
_, err = blobURL2.Download(ctx, 0, 0, azblob.BlobAccessConditions{}, false)
|
||||
_, err = blobURL2.Download(ctx, 0, 0, BlobAccessConditions{}, false)
|
||||
|
||||
// Get permissions via the original container URL so the request succeeds
|
||||
resp, _ := containerURL.GetAccessPolicy(ctx, azblob.LeaseAccessConditions{})
|
||||
resp, _ := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
||||
|
||||
// If we cannot access a blob's data, we will also not be able to enumerate blobs
|
||||
validateStorageError(c, err, azblob.ServiceCodeResourceNotFound)
|
||||
c.Assert(resp.BlobPublicAccess(), chk.Equals, azblob.PublicAccessNone)
|
||||
validateStorageError(c, err, ServiceCodeResourceNotFound)
|
||||
c.Assert(resp.BlobPublicAccess(), chk.Equals, PublicAccessNone)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerSetPermissionsPublicAccessBlob(c *chk.C) {
|
||||
|
@ -652,12 +649,12 @@ func (s *aztestsSuite) TestContainerSetPermissionsPublicAccessBlob(c *chk.C) {
|
|||
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err := containerURL.SetAccessPolicy(ctx, azblob.PublicAccessBlob, nil, azblob.ContainerAccessConditions{})
|
||||
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessBlob, nil, ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := containerURL.GetAccessPolicy(ctx, azblob.LeaseAccessConditions{})
|
||||
resp, err := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.BlobPublicAccess(), chk.Equals, azblob.PublicAccessBlob)
|
||||
c.Assert(resp.BlobPublicAccess(), chk.Equals, PublicAccessBlob)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerSetPermissionsPublicAccessContainer(c *chk.C) {
|
||||
|
@ -666,12 +663,12 @@ func (s *aztestsSuite) TestContainerSetPermissionsPublicAccessContainer(c *chk.C
|
|||
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err := containerURL.SetAccessPolicy(ctx, azblob.PublicAccessContainer, nil, azblob.ContainerAccessConditions{})
|
||||
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessContainer, nil, ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := containerURL.GetAccessPolicy(ctx, azblob.LeaseAccessConditions{})
|
||||
resp, err := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.BlobPublicAccess(), chk.Equals, azblob.PublicAccessContainer)
|
||||
c.Assert(resp.BlobPublicAccess(), chk.Equals, PublicAccessContainer)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerSetPermissionsACLSinglePolicy(c *chk.C) {
|
||||
|
@ -686,18 +683,18 @@ func (s *aztestsSuite) TestContainerSetPermissionsACLSinglePolicy(c *chk.C) {
|
|||
|
||||
start := time.Now().UTC().Add(-15 * time.Second)
|
||||
expiry := start.Add(5 * time.Minute).UTC()
|
||||
permissions := []azblob.SignedIdentifier{{
|
||||
permissions := []SignedIdentifier{{
|
||||
ID: "0000",
|
||||
AccessPolicy: azblob.AccessPolicy{
|
||||
AccessPolicy: AccessPolicy{
|
||||
Start: start,
|
||||
Expiry: expiry,
|
||||
Permission: azblob.AccessPolicyPermission{List: true}.String(),
|
||||
Permission: AccessPolicyPermission{List: true}.String(),
|
||||
},
|
||||
}}
|
||||
_, err = containerURL.SetAccessPolicy(ctx, azblob.PublicAccessNone, permissions, azblob.ContainerAccessConditions{})
|
||||
_, err = containerURL.SetAccessPolicy(ctx, PublicAccessNone, permissions, ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
serviceSASValues := azblob.BlobSASSignatureValues{Identifier: "0000", ContainerName: containerName}
|
||||
serviceSASValues := BlobSASSignatureValues{Identifier: "0000", ContainerName: containerName}
|
||||
queryParams, err := serviceSASValues.NewSASQueryParameters(credential)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
|
@ -705,20 +702,20 @@ func (s *aztestsSuite) TestContainerSetPermissionsACLSinglePolicy(c *chk.C) {
|
|||
|
||||
sasURL := bsu.URL()
|
||||
sasURL.RawQuery = queryParams.Encode()
|
||||
sasPipeline := azblob.NewPipeline(azblob.NewAnonymousCredential(), azblob.PipelineOptions{})
|
||||
sasBlobServiceURL := azblob.NewServiceURL(sasURL, sasPipeline)
|
||||
sasPipeline := NewPipeline(NewAnonymousCredential(), PipelineOptions{})
|
||||
sasBlobServiceURL := NewServiceURL(sasURL, sasPipeline)
|
||||
|
||||
// Verifies that the SAS can access the resource
|
||||
sasContainer := sasBlobServiceURL.NewContainerURL(containerName)
|
||||
resp, err := sasContainer.ListBlobsFlatSegment(ctx, azblob.Marker{}, azblob.ListBlobsSegmentOptions{})
|
||||
resp, err := sasContainer.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Segment.BlobItems[0].Name, chk.Equals, blobName)
|
||||
|
||||
// Verifies that successful sas access is not just because it's public
|
||||
anonymousBlobService := azblob.NewServiceURL(bsu.URL(), sasPipeline)
|
||||
anonymousBlobService := NewServiceURL(bsu.URL(), sasPipeline)
|
||||
anonymousContainer := anonymousBlobService.NewContainerURL(containerName)
|
||||
_, err = anonymousContainer.ListBlobsFlatSegment(ctx, azblob.Marker{}, azblob.ListBlobsSegmentOptions{})
|
||||
validateStorageError(c, err, azblob.ServiceCodeResourceNotFound)
|
||||
_, err = anonymousContainer.ListBlobsFlatSegment(ctx, Marker{}, ListBlobsSegmentOptions{})
|
||||
validateStorageError(c, err, ServiceCodeResourceNotFound)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerSetPermissionsACLMoreThanFive(c *chk.C) {
|
||||
|
@ -729,20 +726,20 @@ func (s *aztestsSuite) TestContainerSetPermissionsACLMoreThanFive(c *chk.C) {
|
|||
|
||||
start := time.Now().UTC()
|
||||
expiry := start.Add(5 * time.Minute).UTC()
|
||||
permissions := make([]azblob.SignedIdentifier, 6, 6)
|
||||
permissions := make([]SignedIdentifier, 6, 6)
|
||||
for i := 0; i < 6; i++ {
|
||||
permissions[i] = azblob.SignedIdentifier{
|
||||
permissions[i] = SignedIdentifier{
|
||||
ID: "000" + strconv.Itoa(i),
|
||||
AccessPolicy: azblob.AccessPolicy{
|
||||
AccessPolicy: AccessPolicy{
|
||||
Start: start,
|
||||
Expiry: expiry,
|
||||
Permission: azblob.AccessPolicyPermission{List: true}.String(),
|
||||
Permission: AccessPolicyPermission{List: true}.String(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
_, err := containerURL.SetAccessPolicy(ctx, azblob.PublicAccessBlob, permissions, azblob.ContainerAccessConditions{})
|
||||
validateStorageError(c, err, azblob.ServiceCodeInvalidXMLDocument)
|
||||
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessBlob, permissions, ContainerAccessConditions{})
|
||||
validateStorageError(c, err, ServiceCodeInvalidXMLDocument)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerSetPermissionsDeleteAndModifyACL(c *chk.C) {
|
||||
|
@ -753,30 +750,30 @@ func (s *aztestsSuite) TestContainerSetPermissionsDeleteAndModifyACL(c *chk.C) {
|
|||
|
||||
start := generateCurrentTimeWithModerateResolution()
|
||||
expiry := start.Add(5 * time.Minute).UTC()
|
||||
permissions := make([]azblob.SignedIdentifier, 2, 2)
|
||||
permissions := make([]SignedIdentifier, 2, 2)
|
||||
for i := 0; i < 2; i++ {
|
||||
permissions[i] = azblob.SignedIdentifier{
|
||||
permissions[i] = SignedIdentifier{
|
||||
ID: "000" + strconv.Itoa(i),
|
||||
AccessPolicy: azblob.AccessPolicy{
|
||||
AccessPolicy: AccessPolicy{
|
||||
Start: start,
|
||||
Expiry: expiry,
|
||||
Permission: azblob.AccessPolicyPermission{List: true}.String(),
|
||||
Permission: AccessPolicyPermission{List: true}.String(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
_, err := containerURL.SetAccessPolicy(ctx, azblob.PublicAccessBlob, permissions, azblob.ContainerAccessConditions{})
|
||||
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessBlob, permissions, ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := containerURL.GetAccessPolicy(ctx, azblob.LeaseAccessConditions{})
|
||||
resp, err := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Items, chk.DeepEquals, permissions)
|
||||
|
||||
permissions = resp.Items[:1] // Delete the first policy by removing it from the slice
|
||||
permissions[0].ID = "0004" // Modify the remaining policy which is at index 0 in the new slice
|
||||
_, err = containerURL.SetAccessPolicy(ctx, azblob.PublicAccessBlob, permissions, azblob.ContainerAccessConditions{})
|
||||
_, err = containerURL.SetAccessPolicy(ctx, PublicAccessBlob, permissions, ContainerAccessConditions{})
|
||||
|
||||
resp, err = containerURL.GetAccessPolicy(ctx, azblob.LeaseAccessConditions{})
|
||||
resp, err = containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Items, chk.HasLen, 1)
|
||||
c.Assert(resp.Items, chk.DeepEquals, permissions)
|
||||
|
@ -790,25 +787,25 @@ func (s *aztestsSuite) TestContainerSetPermissionsDeleteAllPolicies(c *chk.C) {
|
|||
|
||||
start := time.Now().UTC()
|
||||
expiry := start.Add(5 * time.Minute).UTC()
|
||||
permissions := make([]azblob.SignedIdentifier, 2, 2)
|
||||
permissions := make([]SignedIdentifier, 2, 2)
|
||||
for i := 0; i < 2; i++ {
|
||||
permissions[i] = azblob.SignedIdentifier{
|
||||
permissions[i] = SignedIdentifier{
|
||||
ID: "000" + strconv.Itoa(i),
|
||||
AccessPolicy: azblob.AccessPolicy{
|
||||
AccessPolicy: AccessPolicy{
|
||||
Start: start,
|
||||
Expiry: expiry,
|
||||
Permission: azblob.AccessPolicyPermission{List: true}.String(),
|
||||
Permission: AccessPolicyPermission{List: true}.String(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
_, err := containerURL.SetAccessPolicy(ctx, azblob.PublicAccessBlob, permissions, azblob.ContainerAccessConditions{})
|
||||
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessBlob, permissions, ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
_, err = containerURL.SetAccessPolicy(ctx, azblob.PublicAccessBlob, []azblob.SignedIdentifier{}, azblob.ContainerAccessConditions{})
|
||||
_, err = containerURL.SetAccessPolicy(ctx, PublicAccessBlob, []SignedIdentifier{}, ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := containerURL.GetAccessPolicy(ctx, azblob.LeaseAccessConditions{})
|
||||
resp, err := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Items, chk.HasLen, 0)
|
||||
}
|
||||
|
@ -822,19 +819,19 @@ func (s *aztestsSuite) TestContainerSetPermissionsInvalidPolicyTimes(c *chk.C) {
|
|||
// Swap start and expiry
|
||||
expiry := time.Now().UTC()
|
||||
start := expiry.Add(5 * time.Minute).UTC()
|
||||
permissions := make([]azblob.SignedIdentifier, 2, 2)
|
||||
permissions := make([]SignedIdentifier, 2, 2)
|
||||
for i := 0; i < 2; i++ {
|
||||
permissions[i] = azblob.SignedIdentifier{
|
||||
permissions[i] = SignedIdentifier{
|
||||
ID: "000" + strconv.Itoa(i),
|
||||
AccessPolicy: azblob.AccessPolicy{
|
||||
AccessPolicy: AccessPolicy{
|
||||
Start: start,
|
||||
Expiry: expiry,
|
||||
Permission: azblob.AccessPolicyPermission{List: true}.String(),
|
||||
Permission: AccessPolicyPermission{List: true}.String(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
_, err := containerURL.SetAccessPolicy(ctx, azblob.PublicAccessBlob, permissions, azblob.ContainerAccessConditions{})
|
||||
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessBlob, permissions, ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
}
|
||||
|
||||
|
@ -844,7 +841,7 @@ func (s *aztestsSuite) TestContainerSetPermissionsNilPolicySlice(c *chk.C) {
|
|||
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err := containerURL.SetAccessPolicy(ctx, azblob.PublicAccessBlob, nil, azblob.ContainerAccessConditions{})
|
||||
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessBlob, nil, ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
}
|
||||
|
||||
|
@ -860,20 +857,20 @@ func (s *aztestsSuite) TestContainerSetPermissionsSignedIdentifierTooLong(c *chk
|
|||
}
|
||||
expiry := time.Now().UTC()
|
||||
start := expiry.Add(5 * time.Minute).UTC()
|
||||
permissions := make([]azblob.SignedIdentifier, 2, 2)
|
||||
permissions := make([]SignedIdentifier, 2, 2)
|
||||
for i := 0; i < 2; i++ {
|
||||
permissions[i] = azblob.SignedIdentifier{
|
||||
permissions[i] = SignedIdentifier{
|
||||
ID: id,
|
||||
AccessPolicy: azblob.AccessPolicy{
|
||||
AccessPolicy: AccessPolicy{
|
||||
Start: start,
|
||||
Expiry: expiry,
|
||||
Permission: azblob.AccessPolicyPermission{List: true}.String(),
|
||||
Permission: AccessPolicyPermission{List: true}.String(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
_, err := containerURL.SetAccessPolicy(ctx, azblob.PublicAccessBlob, permissions, azblob.ContainerAccessConditions{})
|
||||
validateStorageError(c, err, azblob.ServiceCodeInvalidXMLDocument)
|
||||
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessBlob, permissions, ContainerAccessConditions{})
|
||||
validateStorageError(c, err, ServiceCodeInvalidXMLDocument)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerSetPermissionsIfModifiedSinceTrue(c *chk.C) {
|
||||
|
@ -883,13 +880,13 @@ func (s *aztestsSuite) TestContainerSetPermissionsIfModifiedSinceTrue(c *chk.C)
|
|||
|
||||
defer deleteContainer(c, container)
|
||||
|
||||
_, err := container.SetAccessPolicy(ctx, azblob.PublicAccessNone, nil,
|
||||
azblob.ContainerAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
_, err := container.SetAccessPolicy(ctx, PublicAccessNone, nil,
|
||||
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := container.GetAccessPolicy(ctx, azblob.LeaseAccessConditions{})
|
||||
resp, err := container.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.BlobPublicAccess(), chk.Equals, azblob.PublicAccessNone)
|
||||
c.Assert(resp.BlobPublicAccess(), chk.Equals, PublicAccessNone)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerSetPermissionsIfModifiedSinceFalse(c *chk.C) {
|
||||
|
@ -900,9 +897,9 @@ func (s *aztestsSuite) TestContainerSetPermissionsIfModifiedSinceFalse(c *chk.C)
|
|||
|
||||
currentTime := getRelativeTimeGMT(10)
|
||||
|
||||
_, err := containerURL.SetAccessPolicy(ctx, azblob.PublicAccessNone, nil,
|
||||
azblob.ContainerAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessNone, nil,
|
||||
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerSetPermissionsIfUnModifiedSinceTrue(c *chk.C) {
|
||||
|
@ -913,13 +910,13 @@ func (s *aztestsSuite) TestContainerSetPermissionsIfUnModifiedSinceTrue(c *chk.C
|
|||
|
||||
currentTime := getRelativeTimeGMT(10)
|
||||
|
||||
_, err := containerURL.SetAccessPolicy(ctx, azblob.PublicAccessNone, nil,
|
||||
azblob.ContainerAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessNone, nil,
|
||||
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := containerURL.GetAccessPolicy(ctx, azblob.LeaseAccessConditions{})
|
||||
resp, err := containerURL.GetAccessPolicy(ctx, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.BlobPublicAccess(), chk.Equals, azblob.PublicAccessNone)
|
||||
c.Assert(resp.BlobPublicAccess(), chk.Equals, PublicAccessNone)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerSetPermissionsIfUnModifiedSinceFalse(c *chk.C) {
|
||||
|
@ -930,9 +927,9 @@ func (s *aztestsSuite) TestContainerSetPermissionsIfUnModifiedSinceFalse(c *chk.
|
|||
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err := containerURL.SetAccessPolicy(ctx, azblob.PublicAccessNone, nil,
|
||||
azblob.ContainerAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
_, err := containerURL.SetAccessPolicy(ctx, PublicAccessNone, nil,
|
||||
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfUnmodifiedSince: currentTime}})
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerGetPropertiesAndMetadataNoMetadata(c *chk.C) {
|
||||
|
@ -941,7 +938,7 @@ func (s *aztestsSuite) TestContainerGetPropertiesAndMetadataNoMetadata(c *chk.C)
|
|||
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
resp, err := containerURL.GetProperties(ctx, azblob.LeaseAccessConditions{})
|
||||
resp, err := containerURL.GetProperties(ctx, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.NewMetadata(), chk.HasLen, 0)
|
||||
}
|
||||
|
@ -950,21 +947,21 @@ func (s *aztestsSuite) TestContainerGetPropsAndMetaNonExistantContainer(c *chk.C
|
|||
bsu := getBSU()
|
||||
containerURL, _ := getContainerURL(c, bsu)
|
||||
|
||||
_, err := containerURL.GetProperties(ctx, azblob.LeaseAccessConditions{})
|
||||
validateStorageError(c, err, azblob.ServiceCodeContainerNotFound)
|
||||
_, err := containerURL.GetProperties(ctx, LeaseAccessConditions{})
|
||||
validateStorageError(c, err, ServiceCodeContainerNotFound)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerSetMetadataEmpty(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
containerURL, _ := getContainerURL(c, bsu)
|
||||
_, err := containerURL.Create(ctx, basicMetadata, azblob.PublicAccessBlob)
|
||||
_, err := containerURL.Create(ctx, basicMetadata, PublicAccessBlob)
|
||||
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err = containerURL.SetMetadata(ctx, azblob.Metadata{}, azblob.ContainerAccessConditions{})
|
||||
_, err = containerURL.SetMetadata(ctx, Metadata{}, ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := containerURL.GetProperties(ctx, azblob.LeaseAccessConditions{})
|
||||
resp, err := containerURL.GetProperties(ctx, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.NewMetadata(), chk.HasLen, 0)
|
||||
}
|
||||
|
@ -972,14 +969,14 @@ func (s *aztestsSuite) TestContainerSetMetadataEmpty(c *chk.C) {
|
|||
func (*aztestsSuite) TestContainerSetMetadataNil(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
containerURL, _ := getContainerURL(c, bsu)
|
||||
_, err := containerURL.Create(ctx, basicMetadata, azblob.PublicAccessBlob)
|
||||
_, err := containerURL.Create(ctx, basicMetadata, PublicAccessBlob)
|
||||
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err = containerURL.SetMetadata(ctx, nil, azblob.ContainerAccessConditions{})
|
||||
_, err = containerURL.SetMetadata(ctx, nil, ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := containerURL.GetProperties(ctx, azblob.LeaseAccessConditions{})
|
||||
resp, err := containerURL.GetProperties(ctx, LeaseAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.NewMetadata(), chk.HasLen, 0)
|
||||
}
|
||||
|
@ -990,7 +987,7 @@ func (*aztestsSuite) TestContainerSetMetadataInvalidField(c *chk.C) {
|
|||
|
||||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err := containerURL.SetMetadata(ctx, azblob.Metadata{"!nval!d Field!@#%": "value"}, azblob.ContainerAccessConditions{})
|
||||
_, err := containerURL.SetMetadata(ctx, Metadata{"!nval!d Field!@#%": "value"}, ContainerAccessConditions{})
|
||||
c.Assert(err, chk.NotNil)
|
||||
c.Assert(strings.Contains(err.Error(), invalidHeaderErrorSubstring), chk.Equals, true)
|
||||
}
|
||||
|
@ -999,8 +996,8 @@ func (*aztestsSuite) TestContainerSetMetadataNonExistant(c *chk.C) {
|
|||
bsu := getBSU()
|
||||
containerURL, _ := getContainerURL(c, bsu)
|
||||
|
||||
_, err := containerURL.SetMetadata(ctx, nil, azblob.ContainerAccessConditions{})
|
||||
validateStorageError(c, err, azblob.ServiceCodeContainerNotFound)
|
||||
_, err := containerURL.SetMetadata(ctx, nil, ContainerAccessConditions{})
|
||||
validateStorageError(c, err, ServiceCodeContainerNotFound)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerSetMetadataIfModifiedSinceTrue(c *chk.C) {
|
||||
|
@ -1012,10 +1009,10 @@ func (s *aztestsSuite) TestContainerSetMetadataIfModifiedSinceTrue(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL)
|
||||
|
||||
_, err := containerURL.SetMetadata(ctx, basicMetadata,
|
||||
azblob.ContainerAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err := containerURL.GetProperties(ctx, azblob.LeaseAccessConditions{})
|
||||
resp, err := containerURL.GetProperties(ctx, LeaseAccessConditions{})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.NewMetadata(), chk.DeepEquals, basicMetadata)
|
||||
|
@ -1031,9 +1028,9 @@ func (s *aztestsSuite) TestContainerSetMetadataIfModifiedSinceFalse(c *chk.C) {
|
|||
currentTime := getRelativeTimeGMT(10)
|
||||
|
||||
_, err := containerURL.SetMetadata(ctx, basicMetadata,
|
||||
azblob.ContainerAccessConditions{ModifiedAccessConditions: azblob.ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
ContainerAccessConditions{ModifiedAccessConditions: ModifiedAccessConditions{IfModifiedSince: currentTime}})
|
||||
|
||||
validateStorageError(c, err, azblob.ServiceCodeConditionNotMet)
|
||||
validateStorageError(c, err, ServiceCodeConditionNotMet)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerNewBlobURL(c *chk.C) {
|
||||
|
@ -1044,7 +1041,7 @@ func (s *aztestsSuite) TestContainerNewBlobURL(c *chk.C) {
|
|||
tempBlob := blobURL.URL()
|
||||
tempContainer := containerURL.URL()
|
||||
c.Assert(tempBlob.String(), chk.Equals, tempContainer.String()+"/"+blobPrefix)
|
||||
c.Assert(blobURL, chk.FitsTypeOf, azblob.BlobURL{})
|
||||
c.Assert(blobURL, chk.FitsTypeOf, BlobURL{})
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestContainerNewBlockBlobURL(c *chk.C) {
|
||||
|
@ -1055,5 +1052,5 @@ func (s *aztestsSuite) TestContainerNewBlockBlobURL(c *chk.C) {
|
|||
tempBlob := blobURL.URL()
|
||||
tempContainer := containerURL.URL()
|
||||
c.Assert(tempBlob.String(), chk.Equals, tempContainer.String()+"/"+blobPrefix)
|
||||
c.Assert(blobURL, chk.FitsTypeOf, azblob.BlockBlobURL{})
|
||||
c.Assert(blobURL, chk.FitsTypeOf, BlockBlobURL{})
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,11 +1,10 @@
|
|||
package azblob_test
|
||||
package azblob
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-storage-blob-go/azblob"
|
||||
chk "gopkg.in/check.v1" // go get gopkg.in/check.v1
|
||||
)
|
||||
|
||||
|
@ -15,28 +14,28 @@ func (s *aztestsSuite) TestGetAccountInfo(c *chk.C) {
|
|||
// Ensure the call succeeded. Don't test for specific account properties because we can't/don't want to set account properties.
|
||||
sAccInfo, err := sa.GetAccountInfo(context.Background())
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(*sAccInfo, chk.Not(chk.DeepEquals), azblob.ServiceGetAccountInfoResponse{})
|
||||
c.Assert(*sAccInfo, chk.Not(chk.DeepEquals), ServiceGetAccountInfoResponse{})
|
||||
|
||||
// Test on a container
|
||||
cURL := sa.NewContainerURL(generateContainerName())
|
||||
_, err = cURL.Create(ctx, azblob.Metadata{}, azblob.PublicAccessNone)
|
||||
_, err = cURL.Create(ctx, Metadata{}, PublicAccessNone)
|
||||
c.Assert(err, chk.IsNil)
|
||||
cAccInfo, err := cURL.GetAccountInfo(ctx)
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(*cAccInfo, chk.Not(chk.DeepEquals), azblob.ContainerGetAccountInfoResponse{})
|
||||
c.Assert(*cAccInfo, chk.Not(chk.DeepEquals), ContainerGetAccountInfoResponse{})
|
||||
|
||||
// test on a block blob URL. They all call the same thing on the base URL, so only one test is needed for that.
|
||||
bbURL := cURL.NewBlockBlobURL(generateBlobName())
|
||||
_, err = bbURL.Upload(ctx, strings.NewReader("blah"), azblob.BlobHTTPHeaders{}, azblob.Metadata{}, azblob.BlobAccessConditions{})
|
||||
_, err = bbURL.Upload(ctx, strings.NewReader("blah"), BlobHTTPHeaders{}, Metadata{}, BlobAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
bAccInfo, err := bbURL.GetAccountInfo(ctx)
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(*bAccInfo, chk.Not(chk.DeepEquals), azblob.BlobGetAccountInfoResponse{})
|
||||
c.Assert(*bAccInfo, chk.Not(chk.DeepEquals), BlobGetAccountInfoResponse{})
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestListContainers(c *chk.C) {
|
||||
sa := getBSU()
|
||||
resp, err := sa.ListContainersSegment(context.Background(), azblob.Marker{}, azblob.ListContainersSegmentOptions{Prefix: containerPrefix})
|
||||
resp, err := sa.ListContainersSegment(context.Background(), Marker{}, ListContainersSegmentOptions{Prefix: containerPrefix})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.Response().StatusCode, chk.Equals, 200)
|
||||
c.Assert(resp.RequestID(), chk.Not(chk.Equals), "")
|
||||
|
@ -47,24 +46,24 @@ func (s *aztestsSuite) TestListContainers(c *chk.C) {
|
|||
container, name := createNewContainer(c, sa)
|
||||
defer delContainer(c, container)
|
||||
|
||||
md := azblob.Metadata{
|
||||
md := Metadata{
|
||||
"foo": "foovalue",
|
||||
"bar": "barvalue",
|
||||
}
|
||||
_, err = container.SetMetadata(context.Background(), md, azblob.ContainerAccessConditions{})
|
||||
_, err = container.SetMetadata(context.Background(), md, ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
resp, err = sa.ListContainersSegment(context.Background(), azblob.Marker{}, azblob.ListContainersSegmentOptions{Detail: azblob.ListContainersDetail{Metadata: true}, Prefix: name})
|
||||
resp, err = sa.ListContainersSegment(context.Background(), Marker{}, ListContainersSegmentOptions{Detail: ListContainersDetail{Metadata: true}, Prefix: name})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.ContainerItems, chk.HasLen, 1)
|
||||
c.Assert(resp.ContainerItems[0].Name, chk.NotNil)
|
||||
c.Assert(resp.ContainerItems[0].Properties, chk.NotNil)
|
||||
c.Assert(resp.ContainerItems[0].Properties.LastModified, chk.NotNil)
|
||||
c.Assert(resp.ContainerItems[0].Properties.Etag, chk.NotNil)
|
||||
c.Assert(resp.ContainerItems[0].Properties.LeaseStatus, chk.Equals, azblob.LeaseStatusUnlocked)
|
||||
c.Assert(resp.ContainerItems[0].Properties.LeaseState, chk.Equals, azblob.LeaseStateAvailable)
|
||||
c.Assert(resp.ContainerItems[0].Properties.LeaseStatus, chk.Equals, LeaseStatusUnlocked)
|
||||
c.Assert(resp.ContainerItems[0].Properties.LeaseState, chk.Equals, LeaseStateAvailable)
|
||||
c.Assert(string(resp.ContainerItems[0].Properties.LeaseDuration), chk.Equals, "")
|
||||
c.Assert(string(resp.ContainerItems[0].Properties.PublicAccess), chk.Equals, string(azblob.PublicAccessNone))
|
||||
c.Assert(string(resp.ContainerItems[0].Properties.PublicAccess), chk.Equals, string(PublicAccessNone))
|
||||
c.Assert(resp.ContainerItems[0].Metadata, chk.DeepEquals, md)
|
||||
}
|
||||
|
||||
|
@ -75,7 +74,7 @@ func (s *aztestsSuite) TestListContainersPaged(c *chk.C) {
|
|||
const maxResultsPerPage = 2
|
||||
const pagedContainersPrefix = "azblobspagedtest"
|
||||
|
||||
containers := make([]azblob.ContainerURL, numContainers)
|
||||
containers := make([]ContainerURL, numContainers)
|
||||
for i := 0; i < numContainers; i++ {
|
||||
containers[i], _ = createNewContainerWithSuffix(c, sa, pagedContainersPrefix)
|
||||
}
|
||||
|
@ -86,11 +85,11 @@ func (s *aztestsSuite) TestListContainersPaged(c *chk.C) {
|
|||
}
|
||||
}()
|
||||
|
||||
marker := azblob.Marker{}
|
||||
marker := Marker{}
|
||||
iterations := numContainers / maxResultsPerPage
|
||||
|
||||
for i := 0; i < iterations; i++ {
|
||||
resp, err := sa.ListContainersSegment(context.Background(), marker, azblob.ListContainersSegmentOptions{MaxResults: maxResultsPerPage, Prefix: containerPrefix + pagedContainersPrefix})
|
||||
resp, err := sa.ListContainersSegment(context.Background(), marker, ListContainersSegmentOptions{MaxResults: maxResultsPerPage, Prefix: containerPrefix + pagedContainersPrefix})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(resp.ContainerItems, chk.HasLen, maxResultsPerPage)
|
||||
|
||||
|
@ -107,7 +106,7 @@ func (s *aztestsSuite) TestAccountListContainersEmptyPrefix(c *chk.C) {
|
|||
containerURL2, _ := createNewContainer(c, bsu)
|
||||
defer deleteContainer(c, containerURL2)
|
||||
|
||||
response, err := bsu.ListContainersSegment(ctx, azblob.Marker{}, azblob.ListContainersSegmentOptions{})
|
||||
response, err := bsu.ListContainersSegment(ctx, Marker{}, ListContainersSegmentOptions{})
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(len(response.ContainerItems) >= 2, chk.Equals, true) // The response should contain at least the two created containers. Probably many more
|
||||
|
@ -121,12 +120,12 @@ func (s *aztestsSuite) TestAccountListContainersIncludeTypeMetadata(c *chk.C) {
|
|||
defer deleteContainer(c, containerURLMetadata)
|
||||
|
||||
// Test on containers with and without metadata
|
||||
_, err := containerURLMetadata.SetMetadata(ctx, basicMetadata, azblob.ContainerAccessConditions{})
|
||||
_, err := containerURLMetadata.SetMetadata(ctx, basicMetadata, ContainerAccessConditions{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
// Also validates not specifying MaxResults
|
||||
response, err := bsu.ListContainersSegment(ctx, azblob.Marker{},
|
||||
azblob.ListContainersSegmentOptions{Prefix: containerPrefix, Detail: azblob.ListContainersDetail{Metadata: true}})
|
||||
response, err := bsu.ListContainersSegment(ctx, Marker{},
|
||||
ListContainersSegmentOptions{Prefix: containerPrefix, Detail: ListContainersDetail{Metadata: true}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(response.ContainerItems[0].Name, chk.Equals, nameNoMetadata)
|
||||
c.Assert(response.ContainerItems[0].Metadata, chk.HasLen, 0)
|
||||
|
@ -140,7 +139,7 @@ func (s *aztestsSuite) TestAccountListContainersMaxResultsNegative(c *chk.C) {
|
|||
|
||||
defer deleteContainer(c, containerURL)
|
||||
_, err := bsu.ListContainersSegment(ctx,
|
||||
azblob.Marker{}, *(&azblob.ListContainersSegmentOptions{Prefix: containerPrefix, MaxResults: -2}))
|
||||
Marker{}, *(&ListContainersSegmentOptions{Prefix: containerPrefix, MaxResults: -2}))
|
||||
c.Assert(err, chk.Not(chk.IsNil))
|
||||
}
|
||||
|
||||
|
@ -152,7 +151,7 @@ func (s *aztestsSuite) TestAccountListContainersMaxResultsZero(c *chk.C) {
|
|||
|
||||
// Max Results = 0 means the value will be ignored, the header not set, and the server default used
|
||||
resp, err := bsu.ListContainersSegment(ctx,
|
||||
azblob.Marker{}, *(&azblob.ListContainersSegmentOptions{Prefix: containerPrefix, MaxResults: 0}))
|
||||
Marker{}, *(&ListContainersSegmentOptions{Prefix: containerPrefix, MaxResults: 0}))
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
// There could be existing container
|
||||
|
@ -168,7 +167,7 @@ func (s *aztestsSuite) TestAccountListContainersMaxResultsExact(c *chk.C) {
|
|||
defer deleteContainer(c, containerURL2)
|
||||
|
||||
response, err := bsu.ListContainersSegment(ctx,
|
||||
azblob.Marker{}, *(&azblob.ListContainersSegmentOptions{Prefix: containerPrefix, MaxResults: 2}))
|
||||
Marker{}, *(&ListContainersSegmentOptions{Prefix: containerPrefix, MaxResults: 2}))
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(response.ContainerItems, chk.HasLen, 2)
|
||||
|
@ -183,8 +182,8 @@ func (s *aztestsSuite) TestAccountListContainersMaxResultsInsufficient(c *chk.C)
|
|||
containerURL2, _ := createNewContainer(c, bsu)
|
||||
defer deleteContainer(c, containerURL2)
|
||||
|
||||
response, err := bsu.ListContainersSegment(ctx, azblob.Marker{},
|
||||
*(&azblob.ListContainersSegmentOptions{Prefix: containerPrefix, MaxResults: 1}))
|
||||
response, err := bsu.ListContainersSegment(ctx, Marker{},
|
||||
*(&ListContainersSegmentOptions{Prefix: containerPrefix, MaxResults: 1}))
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
c.Assert(len(response.ContainerItems), chk.Equals, 1)
|
||||
|
@ -197,8 +196,8 @@ func (s *aztestsSuite) TestAccountListContainersMaxResultsSufficient(c *chk.C) {
|
|||
containerURL2, _ := createNewContainer(c, bsu)
|
||||
defer deleteContainer(c, containerURL2)
|
||||
|
||||
response, err := bsu.ListContainersSegment(ctx, azblob.Marker{},
|
||||
*(&azblob.ListContainersSegmentOptions{Prefix: containerPrefix, MaxResults: 3}))
|
||||
response, err := bsu.ListContainersSegment(ctx, Marker{},
|
||||
*(&ListContainersSegmentOptions{Prefix: containerPrefix, MaxResults: 3}))
|
||||
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
|
@ -210,7 +209,7 @@ func (s *aztestsSuite) TestAccountDeleteRetentionPolicy(c *chk.C) {
|
|||
bsu := getBSU()
|
||||
|
||||
days := int32(5)
|
||||
_, err := bsu.SetProperties(ctx, azblob.StorageServiceProperties{DeleteRetentionPolicy: &azblob.RetentionPolicy{Enabled: true, Days: &days}})
|
||||
_, err := bsu.SetProperties(ctx, StorageServiceProperties{DeleteRetentionPolicy: &RetentionPolicy{Enabled: true, Days: &days}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
// From FE, 30 seconds is guaranteed t be enough.
|
||||
|
@ -221,7 +220,7 @@ func (s *aztestsSuite) TestAccountDeleteRetentionPolicy(c *chk.C) {
|
|||
c.Assert(resp.DeleteRetentionPolicy.Enabled, chk.Equals, true)
|
||||
c.Assert(*resp.DeleteRetentionPolicy.Days, chk.Equals, int32(5))
|
||||
|
||||
_, err = bsu.SetProperties(ctx, azblob.StorageServiceProperties{DeleteRetentionPolicy: &azblob.RetentionPolicy{Enabled: false}})
|
||||
_, err = bsu.SetProperties(ctx, StorageServiceProperties{DeleteRetentionPolicy: &RetentionPolicy{Enabled: false}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
// From FE, 30 seconds is guaranteed t be enough.
|
||||
|
@ -237,7 +236,7 @@ func (s *aztestsSuite) TestAccountDeleteRetentionPolicyEmpty(c *chk.C) {
|
|||
bsu := getBSU()
|
||||
|
||||
days := int32(5)
|
||||
_, err := bsu.SetProperties(ctx, azblob.StorageServiceProperties{DeleteRetentionPolicy: &azblob.RetentionPolicy{Enabled: true, Days: &days}})
|
||||
_, err := bsu.SetProperties(ctx, StorageServiceProperties{DeleteRetentionPolicy: &RetentionPolicy{Enabled: true, Days: &days}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
// From FE, 30 seconds is guaranteed t be enough.
|
||||
|
@ -249,7 +248,7 @@ func (s *aztestsSuite) TestAccountDeleteRetentionPolicyEmpty(c *chk.C) {
|
|||
c.Assert(*resp.DeleteRetentionPolicy.Days, chk.Equals, int32(5))
|
||||
|
||||
// Enabled should default to false and therefore disable the policy
|
||||
_, err = bsu.SetProperties(ctx, azblob.StorageServiceProperties{DeleteRetentionPolicy: &azblob.RetentionPolicy{}})
|
||||
_, err = bsu.SetProperties(ctx, StorageServiceProperties{DeleteRetentionPolicy: &RetentionPolicy{}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
// From FE, 30 seconds is guaranteed t be enough.
|
||||
|
@ -265,7 +264,7 @@ func (s *aztestsSuite) TestAccountDeleteRetentionPolicyNil(c *chk.C) {
|
|||
bsu := getBSU()
|
||||
|
||||
days := int32(5)
|
||||
_, err := bsu.SetProperties(ctx, azblob.StorageServiceProperties{DeleteRetentionPolicy: &azblob.RetentionPolicy{Enabled: true, Days: &days}})
|
||||
_, err := bsu.SetProperties(ctx, StorageServiceProperties{DeleteRetentionPolicy: &RetentionPolicy{Enabled: true, Days: &days}})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
// From FE, 30 seconds is guaranteed t be enough.
|
||||
|
@ -276,7 +275,7 @@ func (s *aztestsSuite) TestAccountDeleteRetentionPolicyNil(c *chk.C) {
|
|||
c.Assert(resp.DeleteRetentionPolicy.Enabled, chk.Equals, true)
|
||||
c.Assert(*resp.DeleteRetentionPolicy.Days, chk.Equals, int32(5))
|
||||
|
||||
_, err = bsu.SetProperties(ctx, azblob.StorageServiceProperties{})
|
||||
_, err = bsu.SetProperties(ctx, StorageServiceProperties{})
|
||||
c.Assert(err, chk.IsNil)
|
||||
|
||||
// From FE, 30 seconds is guaranteed t be enough.
|
||||
|
@ -289,14 +288,14 @@ func (s *aztestsSuite) TestAccountDeleteRetentionPolicyNil(c *chk.C) {
|
|||
c.Assert(*resp.DeleteRetentionPolicy.Days, chk.Equals, int32(5))
|
||||
|
||||
// Disable for other tests
|
||||
bsu.SetProperties(ctx, azblob.StorageServiceProperties{DeleteRetentionPolicy: &azblob.RetentionPolicy{Enabled: false}})
|
||||
bsu.SetProperties(ctx, StorageServiceProperties{DeleteRetentionPolicy: &RetentionPolicy{Enabled: false}})
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestAccountDeleteRetentionPolicyDaysTooSmall(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
|
||||
days := int32(0) // Minimum days is 1. Validated on the client.
|
||||
_, err := bsu.SetProperties(ctx, azblob.StorageServiceProperties{DeleteRetentionPolicy: &azblob.RetentionPolicy{Enabled: true, Days: &days}})
|
||||
_, err := bsu.SetProperties(ctx, StorageServiceProperties{DeleteRetentionPolicy: &RetentionPolicy{Enabled: true, Days: &days}})
|
||||
c.Assert(strings.Contains(err.Error(), validationErrorSubstring), chk.Equals, true)
|
||||
}
|
||||
|
||||
|
@ -304,14 +303,14 @@ func (s *aztestsSuite) TestAccountDeleteRetentionPolicyDaysTooLarge(c *chk.C) {
|
|||
bsu := getBSU()
|
||||
|
||||
days := int32(366) // Max days is 365. Left to the service for validation.
|
||||
_, err := bsu.SetProperties(ctx, azblob.StorageServiceProperties{DeleteRetentionPolicy: &azblob.RetentionPolicy{Enabled: true, Days: &days}})
|
||||
validateStorageError(c, err, azblob.ServiceCodeInvalidXMLDocument)
|
||||
_, err := bsu.SetProperties(ctx, StorageServiceProperties{DeleteRetentionPolicy: &RetentionPolicy{Enabled: true, Days: &days}})
|
||||
validateStorageError(c, err, ServiceCodeInvalidXMLDocument)
|
||||
}
|
||||
|
||||
func (s *aztestsSuite) TestAccountDeleteRetentionPolicyDaysOmitted(c *chk.C) {
|
||||
bsu := getBSU()
|
||||
|
||||
// Days is required if enabled is true.
|
||||
_, err := bsu.SetProperties(ctx, azblob.StorageServiceProperties{DeleteRetentionPolicy: &azblob.RetentionPolicy{Enabled: true}})
|
||||
validateStorageError(c, err, azblob.ServiceCodeInvalidXMLDocument)
|
||||
_, err := bsu.SetProperties(ctx, StorageServiceProperties{DeleteRetentionPolicy: &RetentionPolicy{Enabled: true}})
|
||||
validateStorageError(c, err, ServiceCodeInvalidXMLDocument)
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package azblob_test
|
||||
package azblob
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/Azure/azure-storage-blob-go/azblob"
|
||||
chk "gopkg.in/check.v1"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
chk "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
//Creates a container and tests permissions by listing blobs
|
||||
|
@ -19,17 +19,17 @@ func (s *aztestsSuite) TestUserDelegationSASContainer(c *chk.C) {
|
|||
}
|
||||
|
||||
// Create pipeline w/ OAuth to handle user delegation key obtaining
|
||||
p := azblob.NewPipeline(*ocred, azblob.PipelineOptions{})
|
||||
p := NewPipeline(*ocred, PipelineOptions{})
|
||||
|
||||
bsu = bsu.WithPipeline(p)
|
||||
keyInfo := azblob.NewKeyInfo(currentTime, currentTime.Add(48*time.Hour))
|
||||
keyInfo := NewKeyInfo(currentTime, currentTime.Add(48*time.Hour))
|
||||
cudk, err := bsu.GetUserDelegationCredential(ctx, keyInfo, nil, nil)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
cSAS, err := azblob.BlobSASSignatureValues{
|
||||
Protocol: azblob.SASProtocolHTTPS,
|
||||
cSAS, err := BlobSASSignatureValues{
|
||||
Protocol: SASProtocolHTTPS,
|
||||
StartTime: currentTime,
|
||||
ExpiryTime: currentTime.Add(24 * time.Hour),
|
||||
Permissions: "racwdl",
|
||||
|
@ -37,11 +37,11 @@ func (s *aztestsSuite) TestUserDelegationSASContainer(c *chk.C) {
|
|||
}.NewSASQueryParameters(cudk)
|
||||
|
||||
// Create anonymous pipeline
|
||||
p = azblob.NewPipeline(azblob.NewAnonymousCredential(), azblob.PipelineOptions{})
|
||||
p = NewPipeline(NewAnonymousCredential(), PipelineOptions{})
|
||||
|
||||
// Create the container
|
||||
_, err = containerURL.Create(ctx, azblob.Metadata{}, azblob.PublicAccessNone)
|
||||
defer containerURL.Delete(ctx, azblob.ContainerAccessConditions{})
|
||||
_, err = containerURL.Create(ctx, Metadata{}, PublicAccessNone)
|
||||
defer containerURL.Delete(ctx, ContainerAccessConditions{})
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
@ -49,17 +49,17 @@ func (s *aztestsSuite) TestUserDelegationSASContainer(c *chk.C) {
|
|||
// Craft a container URL w/ container UDK SAS
|
||||
cURL := containerURL.URL()
|
||||
cURL.RawQuery += cSAS.Encode()
|
||||
cSASURL := azblob.NewContainerURL(cURL, p)
|
||||
cSASURL := NewContainerURL(cURL, p)
|
||||
|
||||
bblob := cSASURL.NewBlockBlobURL("test")
|
||||
_, err = bblob.Upload(ctx, strings.NewReader("hello world!"), azblob.BlobHTTPHeaders{}, azblob.Metadata{}, azblob.BlobAccessConditions{})
|
||||
_, err = bblob.Upload(ctx, strings.NewReader("hello world!"), BlobHTTPHeaders{}, Metadata{}, BlobAccessConditions{})
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
resp, err := bblob.Download(ctx, 0, 0, azblob.BlobAccessConditions{}, false)
|
||||
resp, err := bblob.Download(ctx, 0, 0, BlobAccessConditions{}, false)
|
||||
data := &bytes.Buffer{}
|
||||
body := resp.Body(azblob.RetryReaderOptions{})
|
||||
body := resp.Body(RetryReaderOptions{})
|
||||
if body == nil {
|
||||
c.Fatal("download body was nil")
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ func (s *aztestsSuite) TestUserDelegationSASContainer(c *chk.C) {
|
|||
}
|
||||
|
||||
c.Assert(data.String(), chk.Equals, "hello world!")
|
||||
_, err = bblob.Delete(ctx, azblob.DeleteSnapshotsOptionNone, azblob.BlobAccessConditions{})
|
||||
_, err = bblob.Delete(ctx, DeleteSnapshotsOptionNone, BlobAccessConditions{})
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
@ -92,19 +92,19 @@ func (s *aztestsSuite) TestUserDelegationSASBlob(c *chk.C) {
|
|||
}
|
||||
|
||||
// Create pipeline to handle requests
|
||||
p := azblob.NewPipeline(*ocred, azblob.PipelineOptions{})
|
||||
p := NewPipeline(*ocred, PipelineOptions{})
|
||||
|
||||
// Prepare user delegation key
|
||||
bsu = bsu.WithPipeline(p)
|
||||
keyInfo := azblob.NewKeyInfo(currentTime, currentTime.Add(48*time.Hour))
|
||||
keyInfo := NewKeyInfo(currentTime, currentTime.Add(48*time.Hour))
|
||||
budk, err := bsu.GetUserDelegationCredential(ctx, keyInfo, nil, nil) //MUST have TokenCredential
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
// Prepare User Delegation SAS query
|
||||
bSAS, err := azblob.BlobSASSignatureValues{
|
||||
Protocol: azblob.SASProtocolHTTPS,
|
||||
bSAS, err := BlobSASSignatureValues{
|
||||
Protocol: SASProtocolHTTPS,
|
||||
StartTime: currentTime,
|
||||
ExpiryTime: currentTime.Add(24 * time.Hour),
|
||||
Permissions: "rd",
|
||||
|
@ -116,32 +116,32 @@ func (s *aztestsSuite) TestUserDelegationSASBlob(c *chk.C) {
|
|||
}
|
||||
|
||||
// Create pipeline
|
||||
p = azblob.NewPipeline(azblob.NewAnonymousCredential(), azblob.PipelineOptions{})
|
||||
p = NewPipeline(NewAnonymousCredential(), PipelineOptions{})
|
||||
|
||||
// Append User Delegation SAS token to URL
|
||||
bSASParts := azblob.NewBlobURLParts(blobURL.URL())
|
||||
bSASParts := NewBlobURLParts(blobURL.URL())
|
||||
bSASParts.SAS = bSAS
|
||||
bSASURL := azblob.NewBlockBlobURL(bSASParts.URL(), p)
|
||||
bSASURL := NewBlockBlobURL(bSASParts.URL(), p)
|
||||
|
||||
// Create container & upload sample data
|
||||
_, err = containerURL.Create(ctx, azblob.Metadata{}, azblob.PublicAccessNone)
|
||||
defer containerURL.Delete(ctx, azblob.ContainerAccessConditions{})
|
||||
_, err = containerURL.Create(ctx, Metadata{}, PublicAccessNone)
|
||||
defer containerURL.Delete(ctx, ContainerAccessConditions{})
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
data := "Hello World!"
|
||||
_, err = blobURL.Upload(ctx, strings.NewReader(data), azblob.BlobHTTPHeaders{ContentType: "text/plain"}, azblob.Metadata{}, azblob.BlobAccessConditions{})
|
||||
_, err = blobURL.Upload(ctx, strings.NewReader(data), BlobHTTPHeaders{ContentType: "text/plain"}, Metadata{}, BlobAccessConditions{})
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
||||
// Download data via User Delegation SAS URL; must succeed
|
||||
downloadResponse, err := bSASURL.Download(ctx, 0, 0, azblob.BlobAccessConditions{}, false)
|
||||
downloadResponse, err := bSASURL.Download(ctx, 0, 0, BlobAccessConditions{}, false)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
downloadedData := &bytes.Buffer{}
|
||||
reader := downloadResponse.Body(azblob.RetryReaderOptions{})
|
||||
reader := downloadResponse.Body(RetryReaderOptions{})
|
||||
_, err = downloadedData.ReadFrom(reader)
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
|
@ -153,7 +153,7 @@ func (s *aztestsSuite) TestUserDelegationSASBlob(c *chk.C) {
|
|||
c.Assert(data, chk.Equals, downloadedData.String())
|
||||
|
||||
// Delete the item using the User Delegation SAS URL; must succeed
|
||||
_, err = bSASURL.Delete(ctx, azblob.DeleteSnapshotsOptionInclude, azblob.BlobAccessConditions{})
|
||||
_, err = bSASURL.Delete(ctx, DeleteSnapshotsOptionInclude, BlobAccessConditions{})
|
||||
if err != nil {
|
||||
c.Fatal(err)
|
||||
}
|
||||
|
|
13
go.mod
13
go.mod
|
@ -1,10 +1,13 @@
|
|||
module github.com/Azure/azure-storage-blob-go
|
||||
module github.com/Azure/azure-kusto-go
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/Azure/azure-pipeline-go v0.2.1
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.0
|
||||
github.com/Azure/go-autorest/autorest v0.10.0 // indirect
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.2
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127
|
||||
)
|
||||
|
||||
go 1.13
|
||||
|
|
24
go.sum
24
go.sum
|
@ -1,23 +1,26 @@
|
|||
github.com/Azure/azure-pipeline-go v0.2.1 h1:OLBdZJ3yvOn2MezlWvbrBMTEUQC72zAftRZOMdj5HYo=
|
||||
github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
|
||||
github.com/Azure/go-autorest v13.3.0+incompatible h1:8Ix0VdeOllBx9jEcZ2Wb1uqWUpE1awmJiaHztwaJCPk=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
||||
github.com/Azure/go-autorest/autorest v0.9.2 h1:6AWuh3uWrsZJcNoCHrCF/+g4aKPCU39kaMO6/qrnK/4=
|
||||
github.com/Azure/go-autorest/autorest v0.10.0 h1:mvdtztBqcL8se7MdrUweNieTNi4kfNG6GOJuurQJpuY=
|
||||
github.com/Azure/go-autorest/autorest v0.10.0/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.0 h1:CxTzQrySOxDnKpLjFJeZAS5Qrv/qFPkgLjx5bOAi//I=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.2 h1:O1X4oexUxnZCaEUGsvMnr8ZGj8HI37tNezwY4npRqA0=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
|
||||
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
|
||||
github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM=
|
||||
github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
|
||||
github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY=
|
||||
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
|
@ -25,9 +28,16 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149 h1:HfxbT6/JcvIljmERptWhwa8XzP7H3T+Z2N26gTsaDaA=
|
||||
github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
Загрузка…
Ссылка в новой задаче