restic/vendor/github.com/Azure/azure-sdk-for-go/storage/file_test.go

418 lines
12 KiB
Go

package storage
// Copyright 2017 Microsoft Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import (
"bytes"
"crypto/md5"
"encoding/base64"
"io"
chk "gopkg.in/check.v1"
)
type StorageFileSuite struct{}
var _ = chk.Suite(&StorageFileSuite{})
func (s *StorageFileSuite) TestCreateFile(c *chk.C) {
cli := getFileClient(c)
cli.deleteAllShares()
rec := cli.client.appendRecorder(c)
defer rec.Stop()
// create share
share := cli.GetShareReference(shareName(c))
c.Assert(share.Create(nil), chk.IsNil)
defer share.Delete(nil)
root := share.GetRootDirectoryReference()
// create directory structure
dir1 := root.GetDirectoryReference("one")
c.Assert(dir1.Create(nil), chk.IsNil)
dir2 := dir1.GetDirectoryReference("two")
c.Assert(dir2.Create(nil), chk.IsNil)
// verify file doesn't exist
file := dir2.GetFileReference("some.file")
exists, err := file.Exists()
c.Assert(err, chk.IsNil)
c.Assert(exists, chk.Equals, false)
// create file
c.Assert(file.Create(1024, nil), chk.IsNil)
// delete file and verify
c.Assert(file.Delete(nil), chk.IsNil)
exists, err = file.Exists()
c.Assert(err, chk.IsNil)
c.Assert(exists, chk.Equals, false)
}
func (s *StorageFileSuite) TestGetFile(c *chk.C) {
cli := getFileClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
// create share
share := cli.GetShareReference(shareName(c))
c.Assert(share.Create(nil), chk.IsNil)
defer share.Delete(nil)
root := share.GetRootDirectoryReference()
// create file
const size = uint64(1024)
byteStream, _ := newByteStream(size)
file := root.GetFileReference("some.file")
c.Assert(file.Create(size, nil), chk.IsNil)
// fill file with some data
c.Assert(file.WriteRange(byteStream, FileRange{End: size - 1}, nil), chk.IsNil)
// set some metadata
md := map[string]string{
"something": "somethingvalue",
"another": "anothervalue",
}
file.Metadata = md
c.Assert(file.SetMetadata(nil), chk.IsNil)
options := GetFileOptions{
GetContentMD5: false,
}
// retrieve full file content and verify
stream, err := file.DownloadRangeToStream(FileRange{Start: 0, End: size - 1}, &options)
c.Assert(err, chk.IsNil)
defer stream.Body.Close()
var b1 [size]byte
count, _ := stream.Body.Read(b1[:])
c.Assert(count, chk.Equals, int(size))
var c1 [size]byte
bs, _ := newByteStream(size)
bs.Read(c1[:])
c.Assert(b1, chk.DeepEquals, c1)
// retrieve partial file content and verify
stream, err = file.DownloadRangeToStream(FileRange{Start: size / 2, End: size - 1}, &options)
c.Assert(err, chk.IsNil)
defer stream.Body.Close()
var b2 [size / 2]byte
count, _ = stream.Body.Read(b2[:])
c.Assert(count, chk.Equals, int(size)/2)
var c2 [size / 2]byte
bs, _ = newByteStream(size / 2)
bs.Read(c2[:])
c.Assert(b2, chk.DeepEquals, c2)
}
func (s *StorageFileSuite) TestFileRanges(c *chk.C) {
cli := getFileClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
share := cli.GetShareReference(shareName(c))
c.Assert(share.Create(nil), chk.IsNil)
defer share.Delete(nil)
root := share.GetRootDirectoryReference()
fileSize := uint64(4096)
contentBytes := content(int(fileSize))
// --- File with no valid ranges
file1 := root.GetFileReference("file1.txt")
c.Assert(file1.Create(fileSize, nil), chk.IsNil)
ranges, err := file1.ListRanges(nil)
c.Assert(err, chk.IsNil)
c.Assert(ranges.ContentLength, chk.Equals, fileSize)
c.Assert(ranges.FileRanges, chk.IsNil)
// --- File after writing a range
file2 := root.GetFileReference("file2.txt")
c.Assert(file2.Create(fileSize, nil), chk.IsNil)
c.Assert(file2.WriteRange(bytes.NewReader(contentBytes), FileRange{End: fileSize - 1}, nil), chk.IsNil)
ranges, err = file2.ListRanges(nil)
c.Assert(err, chk.IsNil)
c.Assert(len(ranges.FileRanges), chk.Equals, 1)
c.Assert((ranges.FileRanges[0].End-ranges.FileRanges[0].Start)+1, chk.Equals, fileSize)
// --- File after writing and clearing
file3 := root.GetFileReference("file3.txt")
c.Assert(file3.Create(fileSize, nil), chk.IsNil)
c.Assert(file3.WriteRange(bytes.NewReader(contentBytes), FileRange{End: fileSize - 1}, nil), chk.IsNil)
c.Assert(file3.ClearRange(FileRange{End: fileSize - 1}, nil), chk.IsNil)
ranges, err = file3.ListRanges(nil)
c.Assert(err, chk.IsNil)
c.Assert(ranges.FileRanges, chk.IsNil)
// --- File with ranges and subranges
file4 := root.GetFileReference("file4.txt")
c.Assert(file4.Create(fileSize, nil), chk.IsNil)
putRanges := []FileRange{
{End: 511},
{Start: 1024, End: 1535},
{Start: 2048, End: 2559},
{Start: 3072, End: 3583},
}
for _, r := range putRanges {
err = file4.WriteRange(bytes.NewReader(contentBytes[:512]), r, nil)
c.Assert(err, chk.IsNil)
}
// validate all ranges
ranges, err = file4.ListRanges(nil)
c.Assert(err, chk.IsNil)
c.Assert(ranges.FileRanges, chk.DeepEquals, putRanges)
options := ListRangesOptions{
ListRange: &FileRange{
Start: 1000,
End: 3000,
},
}
// validate sub-ranges
ranges, err = file4.ListRanges(&options)
c.Assert(err, chk.IsNil)
c.Assert(ranges.FileRanges, chk.DeepEquals, putRanges[1:3])
// --- clear partial range and validate
file5 := root.GetFileReference("file5.txt")
c.Assert(file5.Create(fileSize, nil), chk.IsNil)
c.Assert(file5.WriteRange(bytes.NewReader(contentBytes), FileRange{End: fileSize - 1}, nil), chk.IsNil)
c.Assert(file5.ClearRange(putRanges[0], nil), chk.IsNil)
c.Assert(file5.ClearRange(putRanges[2], nil), chk.IsNil)
ranges, err = file5.ListRanges(nil)
c.Assert(err, chk.IsNil)
expectedtRanges := []FileRange{
{Start: 512, End: 2047},
{Start: 2560, End: 4095},
}
c.Assert(ranges.FileRanges, chk.HasLen, 2)
c.Assert(ranges.FileRanges[0], chk.DeepEquals, expectedtRanges[0])
c.Assert(ranges.FileRanges[1], chk.DeepEquals, expectedtRanges[1])
}
func (s *StorageFileSuite) TestFileProperties(c *chk.C) {
cli := getFileClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
// create share
share := cli.GetShareReference(shareName(c))
c.Assert(share.Create(nil), chk.IsNil)
defer share.Delete(nil)
root := share.GetRootDirectoryReference()
fileSize := uint64(512)
file := root.GetFileReference("test.dat")
c.Assert(file.Create(fileSize, nil), chk.IsNil)
// get initial set of properties
c.Assert(file.Properties.Length, chk.Equals, fileSize)
c.Assert(file.Properties.Etag, chk.NotNil)
// set some file properties
cc := "cachecontrol"
ct := "mytype"
enc := "noencoding"
lang := "neutral"
disp := "friendly"
file.Properties.CacheControl = cc
file.Properties.Type = ct
file.Properties.Disposition = disp
file.Properties.Encoding = enc
file.Properties.Language = lang
c.Assert(file.SetProperties(nil), chk.IsNil)
// retrieve and verify
c.Assert(file.FetchAttributes(nil), chk.IsNil)
c.Assert(file.Properties.CacheControl, chk.Equals, cc)
c.Assert(file.Properties.Type, chk.Equals, ct)
c.Assert(file.Properties.Disposition, chk.Equals, disp)
c.Assert(file.Properties.Encoding, chk.Equals, enc)
c.Assert(file.Properties.Language, chk.Equals, lang)
}
func (s *StorageFileSuite) TestFileMetadata(c *chk.C) {
cli := getFileClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
// create share
share := cli.GetShareReference(shareName(c))
c.Assert(share.Create(nil), chk.IsNil)
defer share.Delete(nil)
root := share.GetRootDirectoryReference()
fileSize := uint64(512)
file := root.GetFileReference("test.dat")
c.Assert(file.Create(fileSize, nil), chk.IsNil)
// get metadata, shouldn't be any
c.Assert(file.Metadata, chk.HasLen, 0)
// set some custom metadata
md := map[string]string{
"something": "somethingvalue",
"another": "anothervalue",
}
file.Metadata = md
c.Assert(file.SetMetadata(nil), chk.IsNil)
// retrieve and verify
c.Assert(file.FetchAttributes(nil), chk.IsNil)
c.Assert(file.Metadata, chk.DeepEquals, md)
}
func (s *StorageFileSuite) TestFileMD5(c *chk.C) {
cli := getFileClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
// create share
share := cli.GetShareReference(shareName(c))
c.Assert(share.Create(nil), chk.IsNil)
defer share.Delete(nil)
root := share.GetRootDirectoryReference()
// create file
const size = uint64(1024)
fileSize := uint64(size)
file := root.GetFileReference("test.dat")
c.Assert(file.Create(fileSize, nil), chk.IsNil)
// fill file with some data and MD5 hash
byteStream, contentMD5 := newByteStream(size)
options := WriteRangeOptions{
ContentMD5: contentMD5,
}
c.Assert(file.WriteRange(byteStream, FileRange{End: size - 1}, &options), chk.IsNil)
// download file and verify
downloadOptions := GetFileOptions{
GetContentMD5: true,
}
stream, err := file.DownloadRangeToStream(FileRange{Start: 0, End: size - 1}, &downloadOptions)
c.Assert(err, chk.IsNil)
defer stream.Body.Close()
c.Assert(stream.ContentMD5, chk.Equals, contentMD5)
}
// returns a byte stream along with a base-64 encoded MD5 hash of its contents
func newByteStream(count uint64) (io.Reader, string) {
b := make([]uint8, count)
for i := uint64(0); i < count; i++ {
b[i] = 0xff
}
// create an MD5 hash of the array
hash := md5.Sum(b)
return bytes.NewReader(b), base64.StdEncoding.EncodeToString(hash[:])
}
func (s *StorageFileSuite) TestCopyFileSameAccountNoMetaData(c *chk.C) {
cli := getFileClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
// create share
share := cli.GetShareReference(shareName(c))
c.Assert(share.Create(nil), chk.IsNil)
defer share.Delete(nil)
root := share.GetRootDirectoryReference()
// create directory structure
dir1 := root.GetDirectoryReference("one")
c.Assert(dir1.Create(nil), chk.IsNil)
dir2 := dir1.GetDirectoryReference("two")
c.Assert(dir2.Create(nil), chk.IsNil)
// create file
file := dir2.GetFileReference("some.file")
c.Assert(file.Create(1024, nil), chk.IsNil)
exists, err := file.Exists()
c.Assert(err, chk.IsNil)
c.Assert(exists, chk.Equals, true)
otherFile := dir2.GetFileReference("someother.file")
// copy the file, no timeout parameter
err = otherFile.CopyFile(file.URL(), nil)
c.Assert(err, chk.IsNil)
// delete files
c.Assert(file.Delete(nil), chk.IsNil)
c.Assert(otherFile.Delete(nil), chk.IsNil)
}
func (s *StorageFileSuite) TestCopyFileSameAccountTimeout(c *chk.C) {
cli := getFileClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
// create share
share := cli.GetShareReference(shareName(c))
c.Assert(share.Create(nil), chk.IsNil)
defer share.Delete(nil)
root := share.GetRootDirectoryReference()
// create directory structure
dir1 := root.GetDirectoryReference("one")
c.Assert(dir1.Create(nil), chk.IsNil)
dir2 := dir1.GetDirectoryReference("two")
c.Assert(dir2.Create(nil), chk.IsNil)
// create file
file := dir2.GetFileReference("some.file")
c.Assert(file.Create(1024, nil), chk.IsNil)
// copy the file, 60 second timeout.
otherFile := dir2.GetFileReference("someother.file")
options := FileRequestOptions{}
options.Timeout = 60
c.Assert(otherFile.CopyFile(file.URL(), &options), chk.IsNil)
// delete files
c.Assert(file.Delete(nil), chk.IsNil)
c.Assert(otherFile.Delete(nil), chk.IsNil)
}
func (s *StorageFileSuite) TestCopyFileMissingFile(c *chk.C) {
cli := getFileClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()
// create share
share := cli.GetShareReference(shareName(c))
c.Assert(share.Create(nil), chk.IsNil)
defer share.Delete(nil)
root := share.GetRootDirectoryReference()
// create directory structure
dir1 := root.GetDirectoryReference("one")
c.Assert(dir1.Create(nil), chk.IsNil)
otherFile := dir1.GetFileReference("someother.file")
// copy the file, no timeout parameter
err := otherFile.CopyFile("", nil)
c.Assert(err, chk.NotNil)
}