-
-
Save frankodoom/f2406921ea62cfc6d1cca70166acd880 to your computer and use it in GitHub Desktop.
Unit testing the functionality to upload files to Azure Blob Storage via REST API. For blog post: http://tech.trailmax.info/2013/11/how-to-test-code-for-accessing-azure-storage-rest-api/
Please note, this implementation only supports file up to 64Mb in size. Anything larger and you need to chop files in pieces and upload them separately. There i…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Net.Http; | |
namespace PackageUploader.Azure | |
{ | |
public class AzureStorageApi | |
{ | |
public void UploadFile(String fullFilePath, String blobSasUri, Dictionary<String, String> metadata = null) | |
{ | |
using (var client = new HttpClient()) | |
using (var fileStream = File.OpenRead(fullFilePath)) | |
{ | |
HttpContent content = new StreamContent(fileStream); | |
content.Headers.Add("x-ms-blob-type", "BlockBlob"); | |
foreach (var pair in metadata ?? new Dictionary<string, string>()) | |
{ | |
content.Headers.Add("x-ms-meta-" + pair.Key, pair.Value); | |
} | |
var response = client.PutAsync(blobSasUri, content).Result; | |
if (response.IsSuccessStatusCode) | |
{ | |
return; | |
} | |
var exceptionMessage = String.Format("Unable to finish request. Server returned status: {0}; {1}", response.StatusCode, response.ReasonPhrase); | |
throw new ApplicationException(exceptionMessage); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Security.Cryptography; | |
using Microsoft.WindowsAzure.Storage; | |
using Microsoft.WindowsAzure.Storage.Blob; | |
using NUnit.Framework; | |
using PackageUploader.Azure; | |
using PackageUploader.Tests.ZeroFriction; | |
namespace PackageUploader.Tests.Azure | |
{ | |
public class BlogPostTests | |
{ | |
private String containerName; | |
private String tempFile; | |
private byte[] uploadedBytes; | |
[TestFixtureSetUp] | |
public void FixtureSetUp() | |
{ | |
StorageEmulator.Start(); | |
} | |
[SetUp] | |
public void SetUp() | |
{ | |
containerName = Guid.NewGuid().ToString().ToLower(); | |
tempFile = Path.GetTempFileName(); | |
var randomNumberGenerator = new RNGCryptoServiceProvider(); | |
uploadedBytes = new byte[128]; | |
randomNumberGenerator.GetBytes(uploadedBytes); | |
File.WriteAllBytes(tempFile, uploadedBytes); | |
} | |
[TearDown] | |
public void TearDown() | |
{ | |
if (File.Exists(tempFile)) | |
{ | |
File.Delete(tempFile); | |
} | |
var container = GetContainerReference(); | |
container.DeleteIfExists(); | |
} | |
private CloudBlobContainer GetContainerReference() | |
{ | |
const string connectionString = "UseDevelopmentStorage=true;DevelopmentStorageProxyUri=http://127.0.0.1"; | |
var container = CloudStorageAccount.Parse(connectionString) | |
.CreateCloudBlobClient() | |
.GetContainerReference(containerName); | |
container.CreateIfNotExists(); | |
return container; | |
} | |
private string GetSasUrl(String filePath) | |
{ | |
var container = GetContainerReference(); | |
var blob = container.GetBlockBlobReference(filePath); | |
var sas = blob.GetSharedAccessSignature(new SharedAccessBlobPolicy() | |
{ | |
Permissions = SharedAccessBlobPermissions.Write, | |
SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(10), | |
}); | |
return String.Format("{0}{1}", blob.Uri, sas); | |
} | |
[Test] | |
public void UploadFile_GivenSas_UploadsFile() | |
{ | |
//Arrange | |
var fileName = Path.GetFileName(tempFile); | |
var sasUri = GetSasUrl(fileName); | |
var sut = new AzureStorageApi(); | |
// Act | |
sut.UploadFile(tempFile, sasUri); | |
// Assert | |
var container = GetContainerReference(); | |
var blob = container.GetBlobReferenceFromServer(fileName); | |
Assert.IsTrue(blob.Exists()); | |
} | |
[Test] | |
public void UploadFile_GivenSas_SavesMetadata() | |
{ | |
//Arrange | |
var fileName = Path.GetFileName(tempFile); | |
var sasUri = GetSasUrl(fileName); | |
var metadata = new Dictionary<String, String>() | |
{ | |
{"Key1", Guid.NewGuid().ToString()}, | |
{"Key2", Guid.NewGuid().ToString()}, | |
}; | |
var sut = new AzureStorageApi(); | |
// Act | |
sut.UploadFile(tempFile, sasUri, metadata); | |
// Assert | |
var container = GetContainerReference(); | |
var blob = container.GetBlobReferenceFromServer(fileName); | |
blob.FetchAttributes(); | |
Assert.AreEqual(metadata, blob.Metadata); | |
} | |
[Test] | |
public void UploadFile_GivenFile_DoesNotModifyFile() | |
{ | |
//Arrange | |
var fileName = Path.GetFileName(tempFile); | |
var sasUri = GetSasUrl(fileName); | |
var sut = new AzureStorageApi(); | |
// Act | |
sut.UploadFile(tempFile, sasUri); | |
// Assert | |
var container = GetContainerReference(); | |
var blob = container.GetBlobReferenceFromServer(fileName); | |
blob.FetchAttributes(); | |
var downloadedBytes = new byte[blob.Properties.Length]; | |
blob.DownloadToByteArray(downloadedBytes, 0); | |
var uploadedString = System.Text.Encoding.UTF8.GetString(uploadedBytes); | |
var downloadedString = System.Text.Encoding.UTF8.GetString(downloadedBytes); | |
Assert.AreEqual(uploadedString, downloadedString); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Diagnostics; | |
using System.Linq; | |
namespace PackageUploader.Tests.ZeroFriction | |
{ | |
public static class StorageEmulator | |
{ | |
public static void Start() | |
{ | |
// check if emulator is already running | |
var processes = Process.GetProcesses().OrderBy(p => p.ProcessName).ToList(); | |
if (processes.Any(process => process.ProcessName.Contains("DSServiceLDB"))) | |
{ | |
return; | |
} | |
//var command = Environment.GetEnvironmentVariable("PROGRAMFILES") + @"\Microsoft SDKs\Windows Azure\Emulator\csrun.exe"; | |
const string command = @"c:\Program Files\Microsoft SDKs\Windows Azure\Emulator\csrun.exe"; | |
using (var process = Process.Start(command, "/devstore:start")) | |
{ | |
process.WaitForExit(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment