in testSuite/cmd/testblob.go [444:599]
func verifySingleBlockBlob(testBlobCmd TestBlobCommand) {
// opening the resource on local path in test directory.
objectLocalPath := testBlobCmd.Object
fileInfo, err := os.Stat(objectLocalPath)
if err != nil {
fmt.Println("error opening the destination blob on local disk ")
os.Exit(1)
}
file, err := os.Open(objectLocalPath)
if err != nil {
fmt.Println("error opening the file ", objectLocalPath)
}
testCtx := context.WithValue(context.Background(), ste.ServiceAPIVersionOverride, defaultServiceApiVersion)
isBlock, err := verifyBlobType(testBlobCmd.Subject, testCtx, "BlockBlob")
if !isBlock || err != nil {
fmt.Println(err)
os.Exit(1)
}
blockBlobClient, err := blockblob.NewClientWithNoCredential(testBlobCmd.Subject, &blockblob.ClientOptions{
ClientOptions: azcore.ClientOptions{
Telemetry: policy.TelemetryOptions{ApplicationID: common.UserAgent},
Retry: policy.RetryOptions{
MaxRetries: ste.UploadMaxTries,
TryTimeout: 10 * time.Minute,
RetryDelay: ste.UploadRetryDelay,
MaxRetryDelay: ste.UploadMaxRetryDelay,
},
Transport: ste.NewAzcopyHTTPClient(0),
}})
if err != nil {
fmt.Printf("error creating block blob client. failed with error %s\n", err.Error())
os.Exit(1)
}
// check for access tier type
// get the blob properties and get the Access Tier Type.
if testBlobCmd.BlobTier != "" {
blobProperties, err := blockBlobClient.GetProperties(testCtx, nil)
if err != nil {
fmt.Printf("error getting the blob properties. Failed with error %s\n", err.Error())
os.Exit(1)
}
// Match the Access Tier Type with Expected Tier Type.
if !strings.EqualFold(common.IffNotNil(blobProperties.AccessTier, ""), testBlobCmd.BlobTier) {
fmt.Printf("block blob access tier %s does not matches the expected tier %s\n", common.IffNotNil(blobProperties.AccessTier, ""), testBlobCmd.BlobTier)
os.Exit(1)
}
// If the access tier type of blob is set to Archive, then the blob is offline and reading the blob is not allowed,
// so exit the test.
if blob.AccessTier(testBlobCmd.BlobTier) == blob.AccessTierArchive {
os.Exit(0)
}
}
get, err := blockBlobClient.DownloadStream(testCtx, nil)
if err != nil {
fmt.Println("unable to get blob properties ", err.Error())
os.Exit(1)
}
// reading all the blob bytes.
blobBytesDownloaded, err := io.ReadAll(get.Body)
if get.Body != nil {
get.Body.Close()
}
if err != nil {
fmt.Println("error reading the byes from response and failed with error ", err.Error())
os.Exit(1)
}
if fileInfo.Size() == 0 {
// If the fileSize is 0 and the len of downloaded bytes is not 0
// validation fails
if len(blobBytesDownloaded) != 0 {
fmt.Printf("validation failed since the actual file size %d differs from the downloaded file size %d\n", fileInfo.Size(), len(blobBytesDownloaded))
os.Exit(1)
}
// If both the actual and downloaded file size is 0,
// validation is successful, no need to match the md5
os.Exit(0)
}
// memory mapping the resource on local path.
mmap, err := NewMMF(file, false, 0, fileInfo.Size())
if err != nil {
fmt.Println("error mapping the destination blob file ", err.Error())
os.Exit(1)
}
// calculating and verify the md5 of the resource
// both locally and on the container.
actualMd5 := md5.Sum(mmap)
expectedMd5 := md5.Sum(blobBytesDownloaded)
if actualMd5 != expectedMd5 {
fmt.Println("the uploaded blob's md5 doesn't matches the actual blob's md5")
os.Exit(1)
}
// verify the user given metadata supplied while uploading the blob against the metadata actually present in the blob
if !validateMetadata(testBlobCmd.Metadata, get.Metadata) {
fmt.Println("meta data does not match between the actual and uploaded blob.")
os.Exit(1)
}
// verify the content-type
expectedContentType := ""
if testBlobCmd.NoGuessMimeType {
expectedContentType = testBlobCmd.ContentType
} else {
expectedContentType = strings.Split(http.DetectContentType(mmap), ";")[0]
}
if testBlobCmd.CheckContentType && !validateString(expectedContentType, common.IffNotNil(get.ContentType, "")) {
fmt.Printf(
"mismatch content type between actual and user given blob content type, expected %q, actually %q\n",
expectedContentType,
common.IffNotNil(get.ContentType, ""))
os.Exit(1)
}
//verify the content-encoding
if !validateString(testBlobCmd.ContentEncoding, common.IffNotNil(get.ContentEncoding, "")) {
fmt.Println("mismatch content encoding between actual and user given blob content encoding")
os.Exit(1)
}
if testBlobCmd.PreserveLastModifiedTime {
if fileInfo.ModTime().Unix() != (common.IffNotNil(get.LastModified, time.Time{})).Unix() {
fmt.Println("modified time of downloaded and actual blob does not match")
os.Exit(1)
}
}
// unmap and closing the memory map file.
mmap.Unmap()
err = file.Close()
if err != nil {
fmt.Printf("error closing the file %s and failed with error %s. Error could be while validating the blob.\n", file.Name(), err.Error())
os.Exit(1)
}
// verify the block size
if testBlobCmd.VerifyBlockOrPageSize {
numberOfBlocks := int(testBlobCmd.NumberOfBlocksOrPages)
resp, err := blockBlobClient.GetBlockList(testCtx, blockblob.BlockListTypeCommitted, nil)
if err != nil {
fmt.Println("error getting the block blob list")
os.Exit(1)
}
// todo only committed blocks
if numberOfBlocks != (len(resp.CommittedBlocks)) {
fmt.Println("number of blocks to be uploaded is different from the number of expected to be uploaded")
os.Exit(1)
}
}
}