Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions Windows.Azure.Msbuild.Test/CleanupAzureStorageContainersTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ninject;
using Rhino.Mocks;
using FluentAssertions.Assertions;
using NUnit.Framework;
using Ninject.MockingKernel.RhinoMock;
using Windows.Azure.Msbuild.AzureTools;
using Microsoft.Build.Framework;
using System.Collections;
using System.IO;
namespace Windows.Azure.Msbuild.Test
{
[TestFixture]
public class CleanupAzureStorageContainersTest
{
[TestCase("http://test.com", "accountName", "accountKey")]
[TestCase("http://test123test.com", "accountName2", "accountKe3")]
public void Execute_CreatesCloudStorageClient(string uri, string accountName, string accountKey)
{
storageFactory.ClearBehavior();

storageFactory.Expect(it => it.Create(new Uri(uri), accountName, accountKey, task.StorageClientTimeoutInMinutes, task.ParallelOptionsThreadCount)).Return(blobClient);

task.Endpoint = uri;
task.StorageAccountName = accountName;
task.StorageAccountKey = accountKey;
task.Execute();

storageFactory.VerifyAllExpectations();
}

[TestCase()]
public void Task_Deletes_TargetContainer()
{
storageFactory.ClearBehavior();

storageFactory.Expect(it => it.Create(new Uri(uri), accountName, accountKey, task.StorageClientTimeoutInMinutes, task.ParallelOptionsThreadCount)).Return(blobClient);

task.Execute();

blobClient.VerifyAllExpectations();
Assert.AreEqual(2, blobContainers.OfType<MockIAzureBlobContainer>().Where(c => !c.DeleteCalled).Count());
Assert.AreEqual(18, blobContainers.OfType<MockIAzureBlobContainer>().Where(c => c.DeleteCalled).Count());
}

public class MockIAzureBlobContainer : IAzureBlobContainer
{
public bool DeleteCalled { get; set; }

public DateTimeOffset? LastModified { get; set; }

public IAzureBlob GetBlobReference(string fileName)
{
throw new NotImplementedException();
}

public IAzureBlob GetBlockBlobReference(string fileName)
{
throw new NotImplementedException();
}

public bool CreateIfNotExists()
{
throw new NotImplementedException();
}

public void Delete()
{
DeleteCalled = true;
}
}
[SetUp]
public void Setup()
{
kernel = new RhinoMocksMockingKernel();
var tempBlobContainers = new List<IAzureBlobContainer>();
for (int i = 0; i < 20; i++)
{
var blobContainer = new MockIAzureBlobContainer()
{
LastModified = DateTimeOffset.Now.Date.AddHours(i),
};

tempBlobContainers.Add(blobContainer);
}

blobContainers = tempBlobContainers;

logger = kernel.Get<ITaskLogger>();
storageFactory = kernel.Get<IAzureBlobClientFactory>();
blobClient = kernel.Get<IAzureBlobClient>();
blob = kernel.Get<IAzureBlob>();

blob.Stub(it => it.DeleteIfExists()).Return(true).Repeat.AtLeastOnce();
storageFactory.Stub(it => it.Create(Arg<Uri>.Is.NotNull, Arg<string>.Is.NotNull, Arg<string>.Is.NotNull, Arg<int>.Is.Anything, Arg<int>.Is.Anything)).Return(blobClient);
blobClient.Stub(it => it.GetAllContainerReferences()).Return(tempBlobContainers);

task = kernel.Get<CleanupAzureStorageContainers>();

accountName = "accountName";
accountKey = "accountKey";

uri = "http://testuri.com";
task.Endpoint = uri;
task.StorageAccountName = accountName;
task.StorageAccountKey = accountKey;
task.RemainingContainers = 2;
}

private string accountKey;
private string accountName;
private IAzureBlob blob;
private IAzureBlobClient blobClient;
private IEnumerable<IAzureBlobContainer> blobContainers;
private ITaskLogger logger;
private CleanupAzureStorageContainers task;
private IAzureBlobClientFactory storageFactory;
private string uri;
private RhinoMocksMockingKernel kernel;
}
}
4 changes: 4 additions & 0 deletions Windows.Azure.Msbuild.Test/Windows.Azure.Msbuild.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="CleanupAzureStorageContainersTest.cs" />
<Compile Include="CopyToAzureStorageTest.cs" />
<Compile Include="ITaskLogger.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
Expand All @@ -82,6 +83,9 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
Expand Down
8 changes: 4 additions & 4 deletions Windows.Azure.Msbuild/AzureTools/AzureBlob.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.WindowsAzure.StorageClient;
using System.IO;
using Microsoft.WindowsAzure.Storage.Blob;

namespace Windows.Azure.Msbuild.AzureTools
{
Expand All @@ -21,15 +21,15 @@ public void UploadFromStream(Stream stream)

public void UploadFile(string fileName)
{
cloudBlob.UploadFile(fileName);
cloudBlob.UploadFromFile(fileName, FileMode.Create);
}

public AzureBlob(CloudBlob cloudBlob)
public AzureBlob(ICloudBlob cloudBlob)
{
this.cloudBlob = cloudBlob;
}

private readonly CloudBlob cloudBlob;
private readonly ICloudBlob cloudBlob;
}
}

24 changes: 18 additions & 6 deletions Windows.Azure.Msbuild/AzureTools/AzureBlobClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
using System.Collections.Generic;
using System.Linq;

using Microsoft.WindowsAzure.StorageClient;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage;

namespace Windows.Azure.Msbuild.AzureTools
{
Expand All @@ -16,19 +18,29 @@ public IAzureBlobContainer GetContainerReference(string containerName)
return new AzureBlobContainer(blobContainer);
}

public IEnumerable<IAzureBlobContainer> GetAllContainerReferences()
{
List<IAzureBlobContainer> azureBlobContainers = new List<IAzureBlobContainer>();
foreach (var container in blobClient.ListContainers())
{
azureBlobContainers.Add(new AzureBlobContainer(container));
}
return azureBlobContainers;
}

public IAzureBlob GetBlobReference(string fileName)
{
var blob = blobClient.GetBlobReference(fileName);
blob.UploadFile(fileName);
var blob = blobClient.GetBlobReferenceFromServer(new StorageUri(new Uri(fileName)));
blob.UploadFromFile(fileName, System.IO.FileMode.Create);
return new AzureBlob(blob);
}

public AzureBlobClient(Uri endpoint, string accountName, string accountKey, int timeoutInMinutes = 30, int parallelOperationThreadCount = 1)
{
var credentials = new StorageCredentialsAccountAndKey(accountName, accountKey);
var credentials = new StorageCredentials(accountName, accountKey);
blobClient = new CloudBlobClient(endpoint, credentials);
blobClient.Timeout = new TimeSpan(0, timeoutInMinutes, 0);
blobClient.ParallelOperationThreadCount = parallelOperationThreadCount;
blobClient.DefaultRequestOptions.MaximumExecutionTime = new TimeSpan(0, timeoutInMinutes, 0);
blobClient.DefaultRequestOptions.ParallelOperationThreadCount = parallelOperationThreadCount;
}

private readonly CloudBlobClient blobClient;
Expand Down
16 changes: 13 additions & 3 deletions Windows.Azure.Msbuild/AzureTools/AzureBlobContainer.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.WindowsAzure.StorageClient;
using System.IO;
using Microsoft.WindowsAzure.Storage.Blob;

namespace Windows.Azure.Msbuild.AzureTools
{
[CoverageExclude(Reason.Delegate)]
public class AzureBlobContainer : IAzureBlobContainer
{
public DateTimeOffset? LastModified
{
get { return container.Properties.LastModified; }
}

public IAzureBlob GetBlobReference(string fileName)
{
var blob = container.GetBlobReference(fileName);
var blob = container.GetBlobReferenceFromServer(fileName);
return new AzureBlob(blob);
}

Expand All @@ -23,7 +28,7 @@ public IAzureBlob GetBlockBlobReference(string fileName)

public bool CreateIfNotExists()
{
return container.CreateIfNotExist();
return container.CreateIfNotExists();
}

public AzureBlobContainer(CloudBlobContainer container)
Expand All @@ -32,6 +37,11 @@ public AzureBlobContainer(CloudBlobContainer container)
}

private readonly CloudBlobContainer container;

public void Delete()
{
container.Delete();
}
}
}

4 changes: 2 additions & 2 deletions Windows.Azure.Msbuild/AzureTools/AzureBlockBlob.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.WindowsAzure.StorageClient;
using System.IO;
using Microsoft.WindowsAzure.Storage.Blob;

namespace Windows.Azure.Msbuild.AzureTools
{
Expand All @@ -21,7 +21,7 @@ public void UploadFromStream(Stream stream)

public void UploadFile(string fileName)
{
blob.UploadFile(fileName);
blob.UploadFromFile(fileName, FileMode.Create);
}

private readonly CloudBlockBlob blob;
Expand Down
3 changes: 3 additions & 0 deletions Windows.Azure.Msbuild/AzureTools/IAzureBlobClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ namespace Windows.Azure.Msbuild.AzureTools
public interface IAzureBlobClient
{
IAzureBlob GetBlobReference(string fileName);

IEnumerable<IAzureBlobContainer> GetAllContainerReferences();

IAzureBlobContainer GetContainerReference(string containerName);
}
}
Expand Down
3 changes: 3 additions & 0 deletions Windows.Azure.Msbuild/AzureTools/IAzureBlobContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ namespace Windows.Azure.Msbuild.AzureTools
{
public interface IAzureBlobContainer
{
DateTimeOffset? LastModified { get; }

IAzureBlob GetBlobReference(string fileName);
IAzureBlob GetBlockBlobReference(string fileName);
bool CreateIfNotExists();
void Delete();
}
}

70 changes: 70 additions & 0 deletions Windows.Azure.Msbuild/CleanupAzureStorageContainers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Windows.Azure.Msbuild.AzureTools;
using System.IO;
using Windows.Azure.Msbuild.Properties;

namespace Windows.Azure.Msbuild
{
public class CleanupAzureStorageContainers : Task
{
public override bool Execute()
{
var msg = "Creating cloud storage client with Endpoint: {0}, StorageAccountKey: {1}, StorageAccountName: {2}";
logger.LogMessage(msg, Endpoint, StorageAccountKey, StorageAccountName);

var endpoint = new Uri(Endpoint);
var client = blobClientWrapper.Create(endpoint, StorageAccountName, StorageAccountKey, StorageClientTimeoutInMinutes, ParallelOptionsThreadCount);

var containers = client.GetAllContainerReferences();
containers = containers.OrderByDescending(c => c.LastModified).Skip(RemainingContainers);
foreach (var container in containers)
{
container.Delete();
}

return true;
}

[CoverageExclude(Reason.Humble)]
public CleanupAzureStorageContainers()
: this(new AzureBlobClientFactory(), null)
{
}

[CoverageExclude(Reason.Test)]
public CleanupAzureStorageContainers(IAzureBlobClientFactory blobClientWrapper, ITaskLogger taskLogger)
{
if (taskLogger == null)
taskLogger = new LoggingHelperWrapper(this);

this.logger = taskLogger;
this.blobClientWrapper = blobClientWrapper;

this.StorageClientTimeoutInMinutes = 30;
this.ParallelOptionsThreadCount = 1;
}

[Required]
public string Endpoint { get; set; }

[Required]
public string StorageAccountKey { get; set; }

[Required]
public string StorageAccountName { get; set; }

[Required]
public int RemainingContainers { get; set; }

public int StorageClientTimeoutInMinutes { get; set; }

public int ParallelOptionsThreadCount { get; set; }

private readonly IAzureBlobClientFactory blobClientWrapper;
private readonly ITaskLogger logger;
}
}
Loading