diff --git a/BreakingChanges.txt b/BreakingChanges.txt index 59782fc22..801c8dae5 100644 --- a/BreakingChanges.txt +++ b/BreakingChanges.txt @@ -1,39 +1,44 @@ -Tracking changes for all breaks since 2.0 - -- Auth Handlers were delay populated in 2.0. They are now going to be populated in the client constructors. They are internally settable. So Test can change it. +Tracking Breaking Changes since 2.0 - maxResults while listing queues in nullable now. -- Table now allows query execution with a resolver against non generic query types(Dynamic Entity types). +- The BlobTypeMismatch and ExtendedErrorUnavailable error strings have changed in SR.cs. -- Container, Blob, Directory, Queue and Table names are now validated at the client side. +- OperationContext.RequestResults does not expose a setter anymore. -- Table now does SAS similar to queues and containers. +- Renamed CloudQueue.EndBeginClear(IAsyncResult) to CloudQueue.EndClear(IAsyncResult). -- All header, query and generic constants are public now so people can use it when they use protocol layer. +- StreamExtensions.WriteToSync(Stream, Stream, long?, long? bool, bool, ExecutionState, StreamDescriptor) now throws InvalidOperationException(SR.StreamLengthError) instead of ArgumentOutOfRangeException("stream"). -- There is now a way users can update their sastoken. This is provided by the StorageCredentials class' updateSas method. +- StreamExtensions.WriteToAsync(stream, Stream, long?, long?, bool, ExecutionState, StreamDescriptor, CancellationToken token) now throws InvalidOperationException(SR.StreamLengthError) instead of ArgumentOutOfRangeException("stream"). -- Users now have an API that takes only the key value when they want to update their key. +- The StorageException thrown when an operation is cancelled now includes an OperationCanceledException as its inner exception. -- Cloud*Blob now has BeginOpenRead and EndOpenRead methods to asynchronously open a stream to read from the blob. +Tracking Breaking Changes since 2.1 RTM -- The BlobTypeMismatch and ExtendedErrorUnavailable error strings have changed in SR.cs. +- When DataServiceContext is used to execute table operations, response received event on OperationContext is no longer fired. -- OperationContext.RequestResults does not have a setter anymore. +- ContinuationTokens are written with an additional element enclosing them if WriteXml() method is used - ReadXml() parser is updated to handle this. -- Renamed CloudQueue.EndBeginClear(IAsyncResult) to CloudQueue.EndClear(IAsyncResult). +- Only the ServiceProperties that are provided are changed. In previous REST versions ommitting a properties section such as Metrics would result in those settings being removed by the service. -- StreamExtensions.WriteToSync(Stream, Stream, long?, long? bool, bool, ExecutionState, StreamDescriptor) now throws InvalidOperationException(SR.StreamLengthError) instead of ArgumentOutOfRangeException("stream"). +- Please refer to the blog post about Breaking Changes on the server side in the new storage protocol version(2013-08-15) here: +http://blogs.msdn.com/b/windowsazurestorage/archive/2013/11/23/windows-azure-storage-breaking-changes-for-windows-azure-tables-november-2013.aspx. -- StreamExtensions.WriteToAsync(stream, Stream, long?, long?, bool, ExecutionState, StreamDescriptor, CancellationToken token) now throws InvalidOperationException(SR.StreamLengthError) instead of ArgumentOutOfRangeException("stream"). +Additionally, the following error messages have changed in the Table Service: -- The StorageException thrown when an operation is cancelled now includes an OperationCanceledException as its inner exception. +Entity over 1MB – -Tracking changes for all breaks since 2.1 RTM +Error message previously - The entity is larger than allowed by the Table Service. +Error message now - The entity is larger than the maximum allowed size (1MB). -- When DataServiceContext is used to execute table operations, response received event on OperationContext is no longer fired. +Batch over 4MB - + +Error message previously - The content length for the requested operation has exceeded the limit. +Error message now - The content length for the requested operation has exceeded the limit (4MB). + +Property name over 255 chars – -- ContinuationTokens are written with an additional element enclosing them if WriteXml() method is used - ReadXml() parser is updated to handle this, but anyone parsing their own could be affected +Error message previously – The property name exceeds the maximum allowed length. +Error message now - The property name exceeds the maximum allowed length (255). -- Only the ServiceProperties that are uploaded are changed. For example, if the user wants to just set CORS, the Logging and Metering related settings elements can be omitted and the omitted settings will be remain unchanged. diff --git a/Lib/ClassLibraryCommon/Blob/CloudBlobContainer.cs b/Lib/ClassLibraryCommon/Blob/CloudBlobContainer.cs index eadaa5fa2..91b815b5e 100644 --- a/Lib/ClassLibraryCommon/Blob/CloudBlobContainer.cs +++ b/Lib/ClassLibraryCommon/Blob/CloudBlobContainer.cs @@ -2394,6 +2394,7 @@ internal RESTCommand AcquireLeaseImpl(TimeSpan? leaseTime, string propos putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, null /* retVal */, cmd, ex); + this.UpdateETagAndLastModified(resp); return BlobHttpResponseParsers.GetLeaseId(resp); }; @@ -2420,7 +2421,12 @@ internal RESTCommand RenewLeaseImpl(AccessCondition accessCondition, B options.ApplyToStorageCommand(putCmd); putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => ContainerHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Renew, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, ctx); putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); + putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => + { + HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); + this.UpdateETagAndLastModified(resp); + return NullType.Value; + }; return putCmd; } @@ -2449,6 +2455,7 @@ internal RESTCommand ChangeLeaseImpl(string proposedLeaseId, AccessCondi putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); + this.UpdateETagAndLastModified(resp); return BlobHttpResponseParsers.GetLeaseId(resp); }; @@ -2475,7 +2482,12 @@ internal RESTCommand ReleaseLeaseImpl(AccessCondition accessCondition, options.ApplyToStorageCommand(putCmd); putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => ContainerHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Release, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, ctx); putCmd.SignRequest = this.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); + putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => + { + HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); + this.UpdateETagAndLastModified(resp); + return NullType.Value; + }; return putCmd; } @@ -2505,6 +2517,7 @@ internal RESTCommand BreakLeaseImpl(TimeSpan? breakPeriod, AccessCondi putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, TimeSpan.Zero, cmd, ex); + this.UpdateETagAndLastModified(resp); int? remainingLeaseTime = BlobHttpResponseParsers.GetRemainingLeaseTime(resp); if (!remainingLeaseTime.HasValue) @@ -2634,7 +2647,7 @@ private RESTCommand SetMetadataImpl(AccessCondition accessCondition, B putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - this.ParseSizeAndLastModified(resp); + this.UpdateETagAndLastModified(resp); return NullType.Value; }; @@ -2664,7 +2677,7 @@ private RESTCommand SetPermissionsImpl(BlobContainerPermissions acl, A putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - this.ParseSizeAndLastModified(resp); + this.UpdateETagAndLastModified(resp); return NullType.Value; }; @@ -2700,7 +2713,7 @@ private RESTCommand GetPermissionsImpl(AccessCondition getCmd.PostProcessResponse = (cmd, resp, ctx) => { ContainerHttpResponseParsers.ReadSharedAccessIdentifiers(cmd.ResponseStream, containerAcl); - this.ParseSizeAndLastModified(resp); + this.UpdateETagAndLastModified(resp); return containerAcl; }; @@ -2802,7 +2815,7 @@ private RESTCommand> ListBlobsImpl(string prefix, i /// Retrieve ETag and LastModified date time from response. /// /// The response to parse. - private void ParseSizeAndLastModified(HttpWebResponse response) + private void UpdateETagAndLastModified(HttpWebResponse response) { BlobContainerProperties parsedProperties = ContainerHttpResponseParsers.GetProperties(response); this.Properties.ETag = parsedProperties.ETag; diff --git a/Lib/ClassLibraryCommon/Blob/CloudBlobSharedImpl.cs b/Lib/ClassLibraryCommon/Blob/CloudBlobSharedImpl.cs index 82a47d1ae..5d86fa991 100644 --- a/Lib/ClassLibraryCommon/Blob/CloudBlobSharedImpl.cs +++ b/Lib/ClassLibraryCommon/Blob/CloudBlobSharedImpl.cs @@ -329,6 +329,7 @@ internal static RESTCommand AcquireLeaseImpl(ICloudBlob blob, BlobAttrib putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, null, cmd, ex); + CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); return BlobHttpResponseParsers.GetLeaseId(resp); }; @@ -359,7 +360,12 @@ internal static RESTCommand RenewLeaseImpl(ICloudBlob blob, BlobAttrib options.ApplyToStorageCommand(putCmd); putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Renew, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, ctx); putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); + putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => + { + HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); + CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); + return NullType.Value; + }; return putCmd; } @@ -393,6 +399,7 @@ internal static RESTCommand ChangeLeaseImpl(ICloudBlob blob, BlobAttribu putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); + CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); return BlobHttpResponseParsers.GetLeaseId(resp); }; @@ -423,7 +430,12 @@ internal static RESTCommand ReleaseLeaseImpl(ICloudBlob blob, BlobAttr options.ApplyToStorageCommand(putCmd); putCmd.BuildRequestDelegate = (uri, builder, serverTimeout, ctx) => BlobHttpWebRequestFactory.Lease(uri, serverTimeout, LeaseAction.Release, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, ctx); putCmd.SignRequest = blob.ServiceClient.AuthenticationHandler.SignRequest; - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); + putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => + { + HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); + CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); + return NullType.Value; + }; return putCmd; } @@ -457,6 +469,7 @@ internal static RESTCommand BreakLeaseImpl(ICloudBlob blob, BlobAttrib putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, TimeSpan.Zero, cmd, ex); + CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); int? remainingLeaseTime = BlobHttpResponseParsers.GetRemainingLeaseTime(resp); if (!remainingLeaseTime.HasValue) diff --git a/Lib/ClassLibraryCommon/Shared/Protocol/HttpWebRequestFactory.cs b/Lib/ClassLibraryCommon/Shared/Protocol/HttpWebRequestFactory.cs index e6150b7c3..25f0ba93a 100644 --- a/Lib/ClassLibraryCommon/Shared/Protocol/HttpWebRequestFactory.cs +++ b/Lib/ClassLibraryCommon/Shared/Protocol/HttpWebRequestFactory.cs @@ -119,6 +119,11 @@ internal static HttpWebRequest GetAcl(Uri uri, UriQueryBuilder builder, int? tim builder.Add(Constants.QueryConstants.Component, "acl"); HttpWebRequest request = CreateWebRequest(WebRequestMethods.Http.Get, uri, timeout, builder, operationContext); + + // Windows phone adds */* as the Accept type when we don't set one explicitly. +#if WINDOWS_PHONE + request.Accept = Constants.XMLAcceptHeaderValue; +#endif return request; } @@ -140,6 +145,11 @@ internal static HttpWebRequest SetAcl(Uri uri, UriQueryBuilder builder, int? tim builder.Add(Constants.QueryConstants.Component, "acl"); HttpWebRequest request = CreateWebRequest(WebRequestMethods.Http.Put, uri, timeout, builder, operationContext); + + // Windows phone adds */* as the Accept type when we don't set one explicitly. +#if WINDOWS_PHONE + request.Accept = Constants.XMLAcceptHeaderValue; +#endif return request; } diff --git a/Lib/ClassLibraryCommon/Table/Protocol/TableOperationHttpResponseParsers.cs b/Lib/ClassLibraryCommon/Table/Protocol/TableOperationHttpResponseParsers.cs index 62d18b4bf..3cf118ba3 100644 --- a/Lib/ClassLibraryCommon/Table/Protocol/TableOperationHttpResponseParsers.cs +++ b/Lib/ClassLibraryCommon/Table/Protocol/TableOperationHttpResponseParsers.cs @@ -361,7 +361,7 @@ private static void ReadQueryResponseUsingJsonParser(ResultSegment internal const string DefaultTableName = "TableName"; + /// + /// Header value to set Accept to XML. + /// + internal const string XMLAcceptHeaderValue = "application/xml"; + /// /// Header value to set Accept to AtomPub. /// @@ -704,7 +709,7 @@ static HeaderConstants() /// /// Specifies the value to use for UserAgent header. /// - public const string UserAgentProductVersion = "3.0.0"; + public const string UserAgentProductVersion = "3.0.1"; /// /// Master Windows Azure Storage header prefix. diff --git a/Lib/WindowsAzure.Storage-Preview.nuspec b/Lib/WindowsAzure.Storage-Preview.nuspec index 79ad47ddd..2d09b6579 100644 --- a/Lib/WindowsAzure.Storage-Preview.nuspec +++ b/Lib/WindowsAzure.Storage-Preview.nuspec @@ -2,7 +2,7 @@ WindowsAzure.Storage-Preview - 3.0.0.0-preview + 3.0.1.0-preview Windows Azure Storage Microsoft Microsoft @@ -11,7 +11,7 @@ http://go.microsoft.com/fwlink/?LinkID=288890 true This client library enables working with the Windows Azure storage services which include the blob service for storing binary and text data, the table service for storing structured non-relational data, and the queue service for storing messages that may be accessed by a client. -For this release see notes - https://github.com/WindowsAzure/azure-sdk-for-net/blob/preview/microsoft-azure-api/Services/Storage/changelog.txt +For this release see notes - https://github.com/WindowsAzure/azure-storage-net/blob/master/README.md and https://github.com/WindowsAzure/azure-storage-net/blob/master/changelog.txt Windows Azure Storage team's blog - http://blogs.msdn.com/b/windowsazurestorage/ A client library for Windows Phone and Windows Runtime for working with Windows Azure storage services including blobs, tables, and queues. Microsoft, Azure, Storage, Table, Blob, Queue, Scalable, winrt, windowsphone, windowsazureofficial diff --git a/Lib/WindowsDesktop/Properties/AssemblyInfo.cs b/Lib/WindowsDesktop/Properties/AssemblyInfo.cs index 32464085c..1f589e49a 100644 --- a/Lib/WindowsDesktop/Properties/AssemblyInfo.cs +++ b/Lib/WindowsDesktop/Properties/AssemblyInfo.cs @@ -34,8 +34,8 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("3.0.0.0")] -[assembly: AssemblyFileVersion("3.0.0.0")] +[assembly: AssemblyVersion("3.0.1.0")] +[assembly: AssemblyFileVersion("3.0.1.0")] #if SIGN [assembly: InternalsVisibleTo( diff --git a/Lib/WindowsDesktop/WindowsAzure.Storage.nuspec b/Lib/WindowsDesktop/WindowsAzure.Storage.nuspec index 4048e73d3..575bd51fa 100644 --- a/Lib/WindowsDesktop/WindowsAzure.Storage.nuspec +++ b/Lib/WindowsDesktop/WindowsAzure.Storage.nuspec @@ -2,7 +2,7 @@ WindowsAzure.Storage - 3.0.0.0 + 3.0.1.0 Windows Azure Storage Microsoft Microsoft @@ -11,13 +11,14 @@ http://go.microsoft.com/fwlink/?LinkID=288890 true This client library enables working with the Windows Azure storage services which include the blob service for storing binary and text data, the table service for storing structured non-relational data, and the queue service for storing messages that may be accessed by a client. -For this release see notes - http://msdn.microsoft.com/en-us/library/windowsazure/jj721952.aspx +For this release see notes - https://github.com/WindowsAzure/azure-storage-net/blob/master/README.md and https://github.com/WindowsAzure/azure-storage-net/blob/master/changelog.txt Windows Azure Storage team's blog - http://blogs.msdn.com/b/windowsazurestorage/ A client library for working with Windows Azure storage services including blobs, tables, and queues. Microsoft, Azure, Storage, Table, Blob, Queue, Scalable, windowsazureofficial + diff --git a/Lib/WindowsPhone/Properties/AssemblyInfo.cs b/Lib/WindowsPhone/Properties/AssemblyInfo.cs index 14ac13042..3bf20a0ff 100644 --- a/Lib/WindowsPhone/Properties/AssemblyInfo.cs +++ b/Lib/WindowsPhone/Properties/AssemblyInfo.cs @@ -32,8 +32,8 @@ // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("3.0.0.0")] -[assembly: AssemblyFileVersion("3.0.0.0")] +[assembly: AssemblyVersion("3.0.1.0")] +[assembly: AssemblyFileVersion("3.0.1.0")] [assembly: NeutralResourcesLanguageAttribute("en-US")] #if SIGN diff --git a/Lib/WindowsRuntime/Blob/CloudBlobContainer.cs b/Lib/WindowsRuntime/Blob/CloudBlobContainer.cs index 7f0be6f58..74193f794 100644 --- a/Lib/WindowsRuntime/Blob/CloudBlobContainer.cs +++ b/Lib/WindowsRuntime/Blob/CloudBlobContainer.cs @@ -661,6 +661,7 @@ internal RESTCommand AcquireLeaseImpl(TimeSpan? leaseTime, string propos putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, null /* retVal */, cmd, ex); + this.UpdateETagAndLastModified(resp); return BlobHttpResponseParsers.GetLeaseId(resp); }; @@ -688,7 +689,12 @@ internal RESTCommand RenewLeaseImpl(AccessCondition accessCondition, B putCmd.Handler = this.ServiceClient.AuthenticationHandler; putCmd.BuildClient = HttpClientFactory.BuildHttpClient; putCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => ContainerHttpRequestMessageFactory.Lease(uri, serverTimeout, LeaseAction.Renew, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); + putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => + { + HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); + this.UpdateETagAndLastModified(resp); + return NullType.Value; + }; return putCmd; } @@ -718,6 +724,7 @@ internal RESTCommand ChangeLeaseImpl(string proposedLeaseId, AccessCondi putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); + this.UpdateETagAndLastModified(resp); return BlobHttpResponseParsers.GetLeaseId(resp); }; @@ -745,7 +752,12 @@ internal RESTCommand ReleaseLeaseImpl(AccessCondition accessCondition, putCmd.Handler = this.ServiceClient.AuthenticationHandler; putCmd.BuildClient = HttpClientFactory.BuildHttpClient; putCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => ContainerHttpRequestMessageFactory.Lease(uri, serverTimeout, LeaseAction.Release, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); + putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => + { + HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); + this.UpdateETagAndLastModified(resp); + return NullType.Value; + }; return putCmd; } @@ -776,6 +788,7 @@ internal RESTCommand BreakLeaseImpl(TimeSpan? breakPeriod, AccessCondi putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, TimeSpan.Zero, cmd, ex); + this.UpdateETagAndLastModified(resp); int? remainingLeaseTime = BlobHttpResponseParsers.GetRemainingLeaseTime(resp); if (!remainingLeaseTime.HasValue) @@ -918,7 +931,7 @@ private RESTCommand SetMetadataImpl(AccessCondition accessCondition, B putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - this.ParseSizeAndLastModified(resp); + this.UpdateETagAndLastModified(resp); return NullType.Value; }; @@ -947,7 +960,7 @@ private RESTCommand SetPermissionsImpl(BlobContainerPermissions acl, A putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); - this.ParseSizeAndLastModified(resp); + this.UpdateETagAndLastModified(resp); return NullType.Value; }; @@ -983,7 +996,7 @@ private RESTCommand GetPermissionsImpl(AccessCondition }; getCmd.PostProcessResponse = (cmd, resp, ctx) => { - this.ParseSizeAndLastModified(resp); + this.UpdateETagAndLastModified(resp); return Task.Factory.StartNew(() => { ContainerHttpResponseParsers.ReadSharedAccessIdentifiers(cmd.ResponseStream, containerAcl); @@ -1093,7 +1106,7 @@ private RESTCommand> ListBlobsImpl(string prefix, i /// Retrieve ETag and LastModified date time from response. /// /// The response to parse. - private void ParseSizeAndLastModified(HttpResponseMessage response) + private void UpdateETagAndLastModified(HttpResponseMessage response) { BlobContainerProperties parsedProperties = ContainerHttpResponseParsers.GetProperties(response); this.Properties.ETag = parsedProperties.ETag; diff --git a/Lib/WindowsRuntime/Blob/CloudBlobSharedImpl.cs b/Lib/WindowsRuntime/Blob/CloudBlobSharedImpl.cs index 0eda1a4d3..52129b277 100644 --- a/Lib/WindowsRuntime/Blob/CloudBlobSharedImpl.cs +++ b/Lib/WindowsRuntime/Blob/CloudBlobSharedImpl.cs @@ -305,6 +305,7 @@ internal static RESTCommand AcquireLeaseImpl(ICloudBlob blob, BlobAttrib putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Created, resp, null /* retVal */, cmd, ex); + CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); return BlobHttpResponseParsers.GetLeaseId(resp); }; @@ -333,7 +334,12 @@ internal static RESTCommand RenewLeaseImpl(ICloudBlob blob, BlobAttrib putCmd.Handler = blob.ServiceClient.AuthenticationHandler; putCmd.BuildClient = HttpClientFactory.BuildHttpClient; putCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => BlobHttpRequestMessageFactory.Lease(uri, serverTimeout, LeaseAction.Renew, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); + putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => + { + HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); + CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); + return NullType.Value; + }; return putCmd; } @@ -365,6 +371,7 @@ internal static RESTCommand ChangeLeaseImpl(ICloudBlob blob, BlobAttribu putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, null /* retVal */, cmd, ex); + CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); return BlobHttpResponseParsers.GetLeaseId(resp); }; @@ -393,7 +400,12 @@ internal static RESTCommand ReleaseLeaseImpl(ICloudBlob blob, BlobAttr putCmd.Handler = blob.ServiceClient.AuthenticationHandler; putCmd.BuildClient = HttpClientFactory.BuildHttpClient; putCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => BlobHttpRequestMessageFactory.Lease(uri, serverTimeout, LeaseAction.Release, null /* proposedLeaseId */, null /* leaseDuration */, null /* leaseBreakPeriod */, accessCondition, cnt, ctx); - putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); + putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => + { + HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp, NullType.Value, cmd, ex); + CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); + return NullType.Value; + }; return putCmd; } @@ -425,6 +437,7 @@ internal static RESTCommand BreakLeaseImpl(ICloudBlob blob, BlobAttrib putCmd.PreProcessResponse = (cmd, resp, ex, ctx) => { HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp, TimeSpan.Zero, cmd, ex); + CloudBlobSharedImpl.UpdateETagLMTAndSequenceNumber(attributes, resp); int? remainingLeaseTime = BlobHttpResponseParsers.GetRemainingLeaseTime(resp); if (!remainingLeaseTime.HasValue) diff --git a/Lib/WindowsRuntime/Properties/AssemblyInfo.cs b/Lib/WindowsRuntime/Properties/AssemblyInfo.cs index 6bfc17f96..dfd156f42 100644 --- a/Lib/WindowsRuntime/Properties/AssemblyInfo.cs +++ b/Lib/WindowsRuntime/Properties/AssemblyInfo.cs @@ -25,8 +25,8 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("3.0.0.0")] -[assembly: AssemblyFileVersion("3.0.0.0")] +[assembly: AssemblyVersion("3.0.1.0")] +[assembly: AssemblyFileVersion("3.0.1.0")] [assembly: ComVisible(false)] #if SIGN diff --git a/Lib/WindowsRuntime/Table/Protocol/TableOperationHttpRequestFactory.cs b/Lib/WindowsRuntime/Table/Protocol/TableOperationHttpRequestFactory.cs index 9825b997c..1bf49be2c 100644 --- a/Lib/WindowsRuntime/Table/Protocol/TableOperationHttpRequestFactory.cs +++ b/Lib/WindowsRuntime/Table/Protocol/TableOperationHttpRequestFactory.cs @@ -29,17 +29,10 @@ namespace Microsoft.WindowsAzure.Storage.Table.Protocol internal class TableOperationHttpRequestMessageFactory { - internal static HttpRequestMessage BuildRequestCore(Uri uri, HttpMethod method, int? timeout, OperationContext ctx) + internal static HttpRequestMessage BuildRequestCore(Uri uri, UriQueryBuilder builder, HttpMethod method, int? timeout, HttpContent content, OperationContext ctx) { - Uri uriRequest = uri; - if (timeout != null && timeout != 0) - { - UriQueryBuilder builder = new UriQueryBuilder(); - builder.Add("timeout", timeout.ToString()); - uriRequest = builder.AddToUri(uri); - } + HttpRequestMessage msg = HttpRequestMessageFactory.CreateRequestMessage(method, uri, timeout, builder, content, ctx); - HttpRequestMessage msg = new HttpRequestMessage(method, uriRequest); msg.Headers.Add("Accept", "application/atom+xml,application/xml"); msg.Headers.Add("Accept-Charset", "UTF-8"); msg.Headers.Add("MaxDataServiceVersion", "2.0;NetFx"); @@ -47,16 +40,16 @@ internal static HttpRequestMessage BuildRequestCore(Uri uri, HttpMethod method, return msg; } - internal static HttpRequestMessage BuildRequestForTableQuery(Uri uri, int? timeout, OperationContext ctx) + internal static HttpRequestMessage BuildRequestForTableQuery(Uri uri, UriQueryBuilder builder, int? timeout, HttpContent content, OperationContext ctx) { - HttpRequestMessage msg = BuildRequestCore(uri, HttpMethod.Get, timeout, ctx); + HttpRequestMessage msg = BuildRequestCore(uri, builder, HttpMethod.Get, timeout, content, ctx); return msg; } - internal static HttpRequestMessage BuildRequestForTableOperation(RESTCommand cmd, Uri uri, int? timeout, TableOperation operation, CloudTableClient client, OperationContext ctx) + internal static HttpRequestMessage BuildRequestForTableOperation(RESTCommand cmd, Uri uri, UriQueryBuilder builder, int? timeout, TableOperation operation, CloudTableClient client, HttpContent content, OperationContext ctx) { - HttpRequestMessage msg = BuildRequestCore(uri, operation.HttpMethod, timeout, ctx); + HttpRequestMessage msg = BuildRequestCore(uri, builder, operation.HttpMethod, timeout, content, ctx); if (operation.OperationType == TableOperationType.InsertOrMerge || operation.OperationType == TableOperationType.Merge) { @@ -98,9 +91,9 @@ internal static HttpRequestMessage BuildRequestForTableOperation(RESTCommand< return msg; } - internal static HttpRequestMessage BuildRequestForTableBatchOperation(RESTCommand cmd, Uri uri, int? timeout, string tableName, TableBatchOperation batch, CloudTableClient client, OperationContext ctx) + internal static HttpRequestMessage BuildRequestForTableBatchOperation(RESTCommand cmd, Uri uri, UriQueryBuilder builder, int? timeout, string tableName, TableBatchOperation batch, CloudTableClient client, HttpContent content, OperationContext ctx) { - HttpRequestMessage msg = BuildRequestCore(NavigationHelper.AppendPathToSingleUri(uri, "$batch"), HttpMethod.Post, timeout, ctx); + HttpRequestMessage msg = BuildRequestCore(NavigationHelper.AppendPathToSingleUri(uri, "$batch"), builder, HttpMethod.Post, timeout, content, ctx); // create the writer, indent for readability of the examples. ODataMessageWriterSettings writerSettings = new ODataMessageWriterSettings() diff --git a/Lib/WindowsRuntime/Table/TableBatchOperation.cs b/Lib/WindowsRuntime/Table/TableBatchOperation.cs index 18a8d11da..5c493769e 100644 --- a/Lib/WindowsRuntime/Table/TableBatchOperation.cs +++ b/Lib/WindowsRuntime/Table/TableBatchOperation.cs @@ -64,7 +64,7 @@ private static RESTCommand> BatchImpl(TableBatchOperation bat batchCmd.RetrieveResponseStream = true; batchCmd.Handler = client.AuthenticationHandler; batchCmd.BuildClient = HttpClientFactory.BuildHttpClient; - batchCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableBatchOperation(cmd, uri, serverTimeout, tableName, batch, client, ctx); + batchCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableBatchOperation(cmd, uri, builder, serverTimeout, tableName, batch, client, cnt, ctx); batchCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.Accepted, resp.StatusCode, results, cmd, ex); batchCmd.PostProcessResponse = (cmd, resp, ctx) => TableOperationHttpResponseParsers.TableBatchOperationPostProcess(results, batch, cmd, resp, ctx); batchCmd.RecoveryAction = (cmd, ex, ctx) => results.Clear(); diff --git a/Lib/WindowsRuntime/Table/TableOperation.cs b/Lib/WindowsRuntime/Table/TableOperation.cs index 81102dcff..2d58169cb 100644 --- a/Lib/WindowsRuntime/Table/TableOperation.cs +++ b/Lib/WindowsRuntime/Table/TableOperation.cs @@ -106,7 +106,7 @@ private static RESTCommand InsertImpl(TableOperation operation, Clo insertCmd.RetrieveResponseStream = true; insertCmd.Handler = client.AuthenticationHandler; insertCmd.BuildClient = HttpClientFactory.BuildHttpClient; - insertCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableOperation(cmd, uri, serverTimeout, operation, client, ctx); + insertCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableOperation(cmd, uri, builder, serverTimeout, operation, client, cnt, ctx); insertCmd.PreProcessResponse = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd, ctx); insertCmd.PostProcessResponse = (cmd, resp, ctx) => TableOperationHttpResponseParsers.TableOperationPostProcess(result, operation, cmd, resp, ctx); @@ -123,7 +123,7 @@ private static RESTCommand DeleteImpl(TableOperation operation, Clo deleteCmd.RetrieveResponseStream = false; deleteCmd.Handler = client.AuthenticationHandler; deleteCmd.BuildClient = HttpClientFactory.BuildHttpClient; - deleteCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableOperation(cmd, uri, serverTimeout, operation, client, ctx); + deleteCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableOperation(cmd, uri, builder, serverTimeout, operation, client, cnt, ctx); deleteCmd.PreProcessResponse = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd, ctx); return deleteCmd; @@ -138,7 +138,7 @@ private static RESTCommand MergeImpl(TableOperation operation, Clou mergeCmd.RetrieveResponseStream = false; mergeCmd.Handler = client.AuthenticationHandler; mergeCmd.BuildClient = HttpClientFactory.BuildHttpClient; - mergeCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableOperation(cmd, uri, serverTimeout, operation, client, ctx); + mergeCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableOperation(cmd, uri, builder, serverTimeout, operation, client, cnt, ctx); mergeCmd.PreProcessResponse = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd, ctx); return mergeCmd; @@ -153,7 +153,7 @@ private static RESTCommand ReplaceImpl(TableOperation operation, Cl replaceCmd.RetrieveResponseStream = false; replaceCmd.Handler = client.AuthenticationHandler; replaceCmd.BuildClient = HttpClientFactory.BuildHttpClient; - replaceCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableOperation(cmd, uri, serverTimeout, operation, client, ctx); + replaceCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableOperation(cmd, uri, builder, serverTimeout, operation, client, cnt, ctx); replaceCmd.PreProcessResponse = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd, ctx); return replaceCmd; @@ -169,7 +169,7 @@ private static RESTCommand RetrieveImpl(TableOperation operation, C retrieveCmd.RetrieveResponseStream = true; retrieveCmd.Handler = client.AuthenticationHandler; retrieveCmd.BuildClient = HttpClientFactory.BuildHttpClient; - retrieveCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableOperation(cmd, uri, serverTimeout, operation, client, ctx); + retrieveCmd.BuildRequest = (cmd, uri, builder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableOperation(cmd, uri, builder, serverTimeout, operation, client, cnt, ctx); retrieveCmd.PreProcessResponse = (cmd, resp, ex, ctx) => TableOperationHttpResponseParsers.TableOperationPreProcess(result, operation, resp, ex, cmd, ctx); retrieveCmd.PostProcessResponse = (cmd, resp, ctx) => Task.Run(async () => diff --git a/Lib/WindowsRuntime/Table/TableQuery.cs b/Lib/WindowsRuntime/Table/TableQuery.cs index 74533c0ea..3aea5eedb 100644 --- a/Lib/WindowsRuntime/Table/TableQuery.cs +++ b/Lib/WindowsRuntime/Table/TableQuery.cs @@ -91,7 +91,7 @@ private static RESTCommand QueryImpl(TableQuery query, TableC queryCmd.Handler = client.AuthenticationHandler; queryCmd.BuildClient = HttpClientFactory.BuildHttpClient; queryCmd.Builder = builder; - queryCmd.BuildRequest = (cmd, uri, queryBuilder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableQuery(uri, serverTimeout, ctx); + queryCmd.BuildRequest = (cmd, uri, queryBuilder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableQuery(uri, builder, serverTimeout, cnt, ctx); queryCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp.StatusCode, null /* retVal */, cmd, ex); queryCmd.PostProcessResponse = async (cmd, resp, ctx) => { diff --git a/Lib/WindowsRuntimeTable/Properties/AssemblyInfo.cs b/Lib/WindowsRuntimeTable/Properties/AssemblyInfo.cs index ce455a593..dbab32ae6 100644 --- a/Lib/WindowsRuntimeTable/Properties/AssemblyInfo.cs +++ b/Lib/WindowsRuntimeTable/Properties/AssemblyInfo.cs @@ -25,8 +25,8 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("3.0.0.0")] -[assembly: AssemblyFileVersion("3.0.0.0")] +[assembly: AssemblyVersion("3.0.1.0")] +[assembly: AssemblyFileVersion("3.0.1.0")] [assembly: ComVisible(false)] #if SIGN diff --git a/Lib/WindowsRuntimeTable/TableQuery.cs b/Lib/WindowsRuntimeTable/TableQuery.cs index 0d75dc460..a4e49a2ee 100644 --- a/Lib/WindowsRuntimeTable/TableQuery.cs +++ b/Lib/WindowsRuntimeTable/TableQuery.cs @@ -140,7 +140,7 @@ internal IAsyncOperation> ExecuteQuerySegmentedAsync< queryCmd.Handler = client.AuthenticationHandler; queryCmd.BuildClient = HttpClientFactory.BuildHttpClient; queryCmd.Builder = builder; - queryCmd.BuildRequest = (cmd, uri, queryBuilder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableQuery(uri, serverTimeout, ctx); + queryCmd.BuildRequest = (cmd, uri, queryBuilder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableQuery(uri, builder, serverTimeout, cnt, ctx); queryCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp.StatusCode, null /* retVal */, cmd, ex); queryCmd.PostProcessResponse = async (cmd, resp, ctx) => { diff --git a/Lib/WindowsRuntimeTable/TableQueryExtensions.cs b/Lib/WindowsRuntimeTable/TableQueryExtensions.cs index 501261379..d34212a72 100644 --- a/Lib/WindowsRuntimeTable/TableQueryExtensions.cs +++ b/Lib/WindowsRuntimeTable/TableQueryExtensions.cs @@ -65,7 +65,7 @@ private static RESTCommand> QueryImpl TableOperationHttpRequestMessageFactory.BuildRequestForTableQuery(uri, serverTimeout, ctx); + queryCmd.BuildRequest = (cmd, uri, queryBuilder, cnt, serverTimeout, ctx) => TableOperationHttpRequestMessageFactory.BuildRequestForTableQuery(uri, builder, serverTimeout, cnt, ctx); queryCmd.PreProcessResponse = (cmd, resp, ex, ctx) => HttpResponseParsers.ProcessExpectedStatusCodeNoException(HttpStatusCode.OK, resp.StatusCode, null /* retVal */, cmd, ex); queryCmd.PostProcessResponse = async (cmd, resp, ctx) => { diff --git a/Lib/WindowsRuntimeTable/WindowsAzure.Storage.Table-Preview.nuspec b/Lib/WindowsRuntimeTable/WindowsAzure.Storage.Table-Preview.nuspec index 0ef301c73..ace605332 100644 --- a/Lib/WindowsRuntimeTable/WindowsAzure.Storage.Table-Preview.nuspec +++ b/Lib/WindowsRuntimeTable/WindowsAzure.Storage.Table-Preview.nuspec @@ -2,7 +2,7 @@ WindowsAzure.Storage.Table-Preview - 3.0.0.0-preview + 3.0.1.0-preview Windows Azure Storage Tables Extension for Windows Runtime Microsoft Microsoft @@ -11,11 +11,12 @@ http://go.microsoft.com/fwlink/?LinkID=288890 true This table extension library provides support for strong entity types (POCOs), generic queries, reflection based serialization and the EntityResolver for languages other than JavaScript when developing Windows Store Apps. +For this release see notes - https://github.com/WindowsAzure/azure-storage-net/blob/master/README.md and https://github.com/WindowsAzure/azure-storage-net/blob/master/changelog.txt Windows Azure Storage team's blog - http://blogs.msdn.com/b/windowsazurestorage/ A table extension library for Windows Runtime for working with Windows Azure Storage tables. Microsoft, Azure, Storage, Table, Scalable, winrt, windowsazureofficial - + diff --git a/Test/ClassLibraryCommon/Blob/LeaseTests.cs b/Test/ClassLibraryCommon/Blob/LeaseTests.cs index 9f7194568..480a78ed1 100644 --- a/Test/ClassLibraryCommon/Blob/LeaseTests.cs +++ b/Test/ClassLibraryCommon/Blob/LeaseTests.cs @@ -239,6 +239,7 @@ internal static void SetAvailableState(ICloudBlob blob) blob.BreakLease(TimeSpan.Zero); blob.Delete(); } + CreateBlob(blob); } @@ -276,6 +277,7 @@ internal static void SetAvailableStateAPM(ICloudBlob blob) blob.Delete(); } } + CreateBlob(blob); } @@ -316,6 +318,7 @@ internal static void SetAvailableStateTask(ICloudBlob blob) blob.DeleteAsync().Wait(); } + CreateBlobTask(blob); } #endif @@ -1081,7 +1084,9 @@ public void BlobAcquireLeaseStateTests() // Acquire the lease while in available state, make idempotent call SetAvailableState(leasedBlob); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); leaseId = leasedBlob.AcquireLease(null /* infinite lease */, proposedLeaseId); + Assert.IsNotNull(leasedBlob.Properties.ETag); leaseId2 = leasedBlob.AcquireLease(null /* infinite lease */, proposedLeaseId); Assert.AreEqual(leaseId, leaseId2); @@ -1158,12 +1163,14 @@ public void BlobAcquireLeaseStateTestsAPM() // Acquire the lease while in available state, make idempotent call SetAvailableStateAPM(leasedBlob); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); IAsyncResult result; using (AutoResetEvent waitHandle = new AutoResetEvent(false)) { result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); waitHandle.WaitOne(); leaseId = leasedBlob.EndAcquireLease(result); + Assert.IsNotNull(leasedBlob.Properties.ETag); result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); waitHandle.WaitOne(); @@ -1275,12 +1282,14 @@ public void PageBlobAcquireLeaseStateTestsAPM() // Acquire the lease while in available state, make idempotent call SetAvailableStateAPM(leasedBlob); + leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); IAsyncResult result; using (AutoResetEvent waitHandle = new AutoResetEvent(false)) { result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); waitHandle.WaitOne(); leaseId = leasedBlob.EndAcquireLease(result); + Assert.IsNotNull(leasedBlob.Properties.ETag); result = leasedBlob.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); waitHandle.WaitOne(); @@ -1392,9 +1401,9 @@ public void BlobAcquireLeaseStateTestsTask() // Acquire the lease while in available state, make idempotent call SetAvailableStateTask(leasedBlob); - + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); leaseId = leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Result; - + Assert.IsNotNull(leasedBlob.Properties.ETag); leaseId2 = leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Result; Assert.AreEqual(leaseId, leaseId2); @@ -1478,8 +1487,9 @@ public void PageBlobAcquireLeaseStateTestsTask() // Acquire the lease while in available state, make idempotent call SetAvailableStateTask(leasedBlob); - + leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); leaseId = leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Result; + Assert.IsNotNull(leasedBlob.Properties.ETag); leaseId2 = leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Result; Assert.AreEqual(leaseId, leaseId2); @@ -1571,7 +1581,9 @@ public void BlobRenewLeaseStateTests() // Renew infinite lease leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedBlob.Properties.ETag); // Renew infinite lease (wrong lease) leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); @@ -1702,7 +1714,9 @@ public void PageBlobRenewLeaseStateTests() // Renew infinite lease leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); leasedBlob.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedBlob.Properties.ETag); // Renew infinite lease (wrong lease) leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); @@ -1837,9 +1851,11 @@ public void BlobRenewLeaseStateTestsAPM() // Renew infinite lease leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); waitHandle.WaitOne(); leasedBlob.EndRenewLease(result); + Assert.IsNotNull(leasedBlob.Properties.ETag); // Renew infinite lease (wrong lease) leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); @@ -2004,9 +2020,11 @@ public void PageBlobRenewLeaseStateTestsAPM() // Renew infinite lease leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); result = leasedBlob.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); waitHandle.WaitOne(); leasedBlob.EndRenewLease(result); + Assert.IsNotNull(leasedBlob.Properties.ETag); // Renew infinite lease (wrong lease) leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); @@ -2168,7 +2186,9 @@ public void BlobRenewLeaseStateTestsTask() // Renew infinite lease leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); + Assert.IsNotNull(leasedBlob.Properties.ETag); // Renew infinite lease (wrong lease) leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); @@ -2299,7 +2319,9 @@ public void PageBlobRenewLeaseStateTestsTask() // Renew infinite lease leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); + Assert.IsNotNull(leasedBlob.Properties.ETag); // Renew infinite lease (wrong lease) leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); @@ -2433,7 +2455,9 @@ public void BlobChangeLeaseStateTests() // Change leased lease, with idempotent change leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); leaseId2 = leasedBlob.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedBlob.Properties.ETag); leaseId2 = leasedBlob.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); // Change a leased lease, with same proposed ID but different lease ID @@ -2527,7 +2551,9 @@ public void PageBlobChangeLeaseStateTests() // Change leased lease, with idempotent change leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); leaseId2 = leasedBlob.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedBlob.Properties.ETag); leaseId2 = leasedBlob.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); // Change a leased lease, with same proposed ID but different lease ID @@ -2626,9 +2652,11 @@ public void BlobChangeLeaseStateTestsAPM() // Change leased lease, with idempotent change leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); result = leasedBlob.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); waitHandle.WaitOne(); leasedBlob.EndChangeLease(result); + Assert.IsNotNull(leasedBlob.Properties.ETag); result = leasedBlob.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); waitHandle.WaitOne(); leasedBlob.EndChangeLease(result); @@ -2752,9 +2780,11 @@ public void PageBlobChangeLeaseStateTestsAPM() // Change leased lease, with idempotent change leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); result = leasedBlob.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); waitHandle.WaitOne(); leasedBlob.EndChangeLease(result); + Assert.IsNotNull(leasedBlob.Properties.ETag); result = leasedBlob.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); waitHandle.WaitOne(); leasedBlob.EndChangeLease(result); @@ -2874,7 +2904,9 @@ public void BlobChangeLeaseStateTestsTask() // Change leased lease, with idempotent change leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); leaseId2 = leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)).Result; + Assert.IsNotNull(leasedBlob.Properties.ETag); leaseId2 = leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)).Result; // Change a leased lease, with same proposed ID but different lease ID @@ -2911,7 +2943,9 @@ public void PageBlobChangeLeaseStateTestsTask() // Change leased lease, with idempotent change leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); leaseId2 = leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)).Result; + Assert.IsNotNull(leasedBlob.Properties.ETag); leaseId2 = leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)).Result; // Change a leased lease, with same proposed ID but different lease ID @@ -2955,7 +2989,9 @@ public void BlobReleaseLeaseStateTests() // Release lease (right lease) leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedBlob.Properties.ETag); // Release lease in released state (old lease) leaseId = SetReleasedState(leasedBlob, null /* infinite lease */); @@ -3032,7 +3068,9 @@ public void PageBlobReleaseLeaseStateTests() // Release lease (right lease) leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); leasedBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedBlob.Properties.ETag); // Release lease in released state (old lease) leaseId = SetReleasedState(leasedBlob, null /* infinite lease */); @@ -3116,9 +3154,11 @@ public void BlobReleaseLeaseStateTestsAPM() // Release lease (right lease) leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); waitHandle.WaitOne(); leasedBlob.EndReleaseLease(result); + Assert.IsNotNull(leasedBlob.Properties.ETag); // Release lease in released state (old lease) leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); @@ -3217,9 +3257,11 @@ public void PageBlobReleaseLeaseStateTestsAPM() // Release lease (right lease) leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); result = leasedBlob.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); waitHandle.WaitOne(); leasedBlob.EndReleaseLease(result); + Assert.IsNotNull(leasedBlob.Properties.ETag); // Release lease in released state (old lease) leaseId = SetReleasedStateAPM(leasedBlob, null /* infinite lease */); @@ -3312,7 +3354,9 @@ public void BlobReleaseLeaseStateTestsTask() // Release lease (right lease) leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, new OperationContext()).Wait(); + Assert.IsNotNull(leasedBlob.Properties.ETag); this.DeleteAllTask(); } @@ -3349,7 +3393,9 @@ public void PageBlobReleaseLeaseStateTestsTask() // Release lease (right lease) leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); - leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, new OperationContext()); + leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); + leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId), null, new OperationContext()).Wait(); + Assert.IsNotNull(leasedBlob.Properties.ETag); this.DeleteAllTask(); } @@ -3379,7 +3425,9 @@ public void BlobBreakLeaseStateTests() // Break infinite lease (default break time) leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); leaseTime = leasedBlob.BreakLease(null /* default break period */); + Assert.IsNotNull(leasedBlob.Properties.ETag); Assert.AreEqual(TimeSpan.Zero, leaseTime); // Break infinite lease (zero break time) @@ -3464,7 +3512,9 @@ public void PageBlobBreakLeaseStateTests() // Break infinite lease (default break time) leaseId = SetLeasedState(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); leaseTime = leasedBlob.BreakLease(null /* default break period */); + Assert.IsNotNull(leasedBlob.Properties.ETag); Assert.AreEqual(TimeSpan.Zero, leaseTime); // Break infinite lease (zero break time) @@ -3555,9 +3605,11 @@ public void BlobBreakLeaseStateTestsAPM() // Break infinite lease (default break time) leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); result = leasedBlob.BeginBreakLease(null /* default break period */, ar => waitHandle.Set(), null); waitHandle.WaitOne(); leaseTime = leasedBlob.EndBreakLease(result); + Assert.IsNotNull(leasedBlob.Properties.ETag); Assert.AreEqual(TimeSpan.Zero, leaseTime); // Break infinite lease (zero break time) @@ -3674,9 +3726,11 @@ public void PageBlobBreakLeaseStateTestsAPM() // Break infinite lease (default break time) leaseId = SetLeasedStateAPM(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); result = leasedBlob.BeginBreakLease(null /* default break period */, ar => waitHandle.Set(), null); waitHandle.WaitOne(); leaseTime = leasedBlob.EndBreakLease(result); + Assert.IsNotNull(leasedBlob.Properties.ETag); Assert.AreEqual(TimeSpan.Zero, leaseTime); // Break infinite lease (zero break time) @@ -3789,7 +3843,9 @@ public void BlobBreakLeaseStateTestsTask() // Break infinite lease (default break time) leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); leaseTime = leasedBlob.BreakLeaseAsync(null /* default break period */).Result; + Assert.IsNotNull(leasedBlob.Properties.ETag); Assert.AreEqual(TimeSpan.Zero, leaseTime); // Break infinite lease (zero break time) @@ -3875,7 +3931,9 @@ public void PageBlobBreakLeaseStateTestsTask() // Break infinite lease (default break time) leaseId = SetLeasedStateTask(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetPageBlobReference("LeasedBlob"); leaseTime = leasedBlob.BreakLeaseAsync(null /* default break period */).Result; + Assert.IsNotNull(leasedBlob.Properties.ETag); Assert.AreEqual(TimeSpan.Zero, leaseTime); // Break infinite lease (zero break time) @@ -5624,7 +5682,9 @@ public void ContainerAcquireLeaseStateTests() // Acquire the lease while in available state, make idempotent call SetUnleasedState(leasedContainer); + leasedContainer = this.GetContainerReference("lease-tests"); leaseId = leasedContainer.AcquireLease(null /* infinite lease */, proposedLeaseId); + Assert.IsNotNull(leasedContainer.Properties.ETag); leaseId2 = leasedContainer.AcquireLease(null /* infinite lease */, proposedLeaseId); Assert.AreEqual(leaseId, leaseId2); @@ -5703,9 +5763,11 @@ public void ContainerAcquireLeaseStateTestsAPM() SetUnleasedStateAPM(leasedContainer); using (AutoResetEvent waitHandle = new AutoResetEvent(false)) { + leasedContainer = this.GetContainerReference("lease-tests"); IAsyncResult result = leasedContainer.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); waitHandle.WaitOne(); leaseId = leasedContainer.EndAcquireLease(result); + Assert.IsNotNull(leasedContainer.Properties.ETag); result = leasedContainer.BeginAcquireLease(null /* infinite lease */, proposedLeaseId, ar => waitHandle.Set(), null); waitHandle.WaitOne(); @@ -5813,7 +5875,9 @@ public void ContainerAcquireLeaseStateTestsTask() // Acquire the lease while in available state, make idempotent call SetUnleasedState(leasedContainer); + leasedContainer = this.GetContainerReference("lease-tests"); leaseId = leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Result; + Assert.IsNotNull(leasedContainer.Properties.ETag); leaseId2 = leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId).Result; Assert.AreEqual(leaseId, leaseId2); @@ -5898,7 +5962,9 @@ public void ContainerRenewLeaseStateTests() // Renew infinite lease leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); leasedContainer.RenewLease(AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedContainer.Properties.ETag); // Renew infinite lease (wrong lease) leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); @@ -6028,9 +6094,11 @@ public void ContainerRenewLeaseStateTestsAPM() // Renew infinite lease leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); result = leasedContainer.BeginRenewLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); waitHandle.WaitOne(); leasedContainer.EndRenewLease(result); + Assert.IsNotNull(leasedContainer.Properties.ETag); // Renew infinite lease (wrong lease) leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); @@ -6186,7 +6254,9 @@ public void ContainerRenewLeaseStateTestsTask() // Renew infinite lease leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); + Assert.IsNotNull(leasedContainer.Properties.ETag); // Renew infinite lease (wrong lease) leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); @@ -6316,7 +6386,9 @@ public void ContainerChangeLeaseStateTests() // Change leased lease, with idempotent change leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); leaseId2 = leasedContainer.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedContainer.Properties.ETag); leaseId2 = leasedContainer.ChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); // Change a leased lease, with same proposed ID but different lease ID @@ -6414,9 +6486,11 @@ public void ContainerChangeLeaseStateTestsAPM() // Change leased lease, with idempotent change leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); result = leasedContainer.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); waitHandle.WaitOne(); leaseId2 = leasedContainer.EndChangeLease(result); + Assert.IsNotNull(leasedContainer.Properties.ETag); result = leasedContainer.BeginChangeLease(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); waitHandle.WaitOne(); leaseId2 = leasedContainer.EndChangeLease(result); @@ -6533,7 +6607,9 @@ public void ContainerChangeLeaseStateTestsTask() // Change leased lease, with idempotent change leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); leaseId2 = leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)).Result; + Assert.IsNotNull(leasedContainer.Properties.ETag); leaseId2 = leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)).Result; // Change a leased lease, with same proposed ID but different lease ID @@ -6634,7 +6710,9 @@ public void ContainerReleaseLeaseStateTests() // Release lease (right lease) leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); leasedContainer.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedContainer.Properties.ETag); // Release lease in released state (old lease) leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); @@ -6717,9 +6795,11 @@ public void ContainerReleaseLeaseStateTestsAPM() // Release lease (right lease) leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); result = leasedContainer.BeginReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId), ar => waitHandle.Set(), null); waitHandle.WaitOne(); leasedContainer.EndReleaseLease(result); + Assert.IsNotNull(leasedContainer.Properties.ETag); // Release lease in released state (old lease) leaseId = SetReleasedStateAPM(leasedContainer, null /* infinite lease */); @@ -6810,7 +6890,9 @@ public void ContainerReleaseLeaseStateTestsTask() // Release lease (right lease) leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)).Wait(); + Assert.IsNotNull(leasedContainer.Properties.ETag); // Release lease in released state (old lease) leaseId = SetReleasedState(leasedContainer, null /* infinite lease */); @@ -6879,7 +6961,9 @@ public void ContainerBreakLeaseStateTests() // Break infinite lease (default break time) leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); leaseTime = leasedContainer.BreakLease(null /* default break period */); + Assert.IsNotNull(leasedContainer.Properties.ETag); Assert.AreEqual(TimeSpan.Zero, leaseTime); // Break infinite lease (zero break time) @@ -6967,9 +7051,11 @@ public void ContainerBreakLeaseStateTestsAPM() // Break infinite lease (default break time) leaseId = SetLeasedStateAPM(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); result = leasedContainer.BeginBreakLease(null /* default break period */, ar => waitHandle.Set(), null); waitHandle.WaitOne(); leaseTime = leasedContainer.EndBreakLease(result); + Assert.IsNotNull(leasedContainer.Properties.ETag); Assert.AreEqual(TimeSpan.Zero, leaseTime); // Break infinite lease (zero break time) @@ -7078,7 +7164,9 @@ public void ContainerBreakLeaseStateTestsTask() // Break infinite lease (default break time) leaseId = SetLeasedState(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); leaseTime = leasedContainer.BreakLeaseAsync(null /* default break period */).Result; + Assert.IsNotNull(leasedContainer.Properties.ETag); Assert.AreEqual(TimeSpan.Zero, leaseTime); // Break infinite lease (zero break time) diff --git a/Test/Common/TestHelper.Common.cs b/Test/Common/TestHelper.Common.cs index 3b9ef2f63..99a4f89eb 100644 --- a/Test/Common/TestHelper.Common.cs +++ b/Test/Common/TestHelper.Common.cs @@ -292,7 +292,7 @@ internal static void ValidateResponse(OperationContext opContext, int expectedAt { TestHelper.AssertNAttempts(opContext, 1); Assert.AreEqual(opContext.LastResult.HttpStatusCode, expectedStatusCode); - Assert.IsTrue(allowedErrorCodes.Contains(opContext.LastResult.ExtendedErrorInformation.ErrorCode), "Unexpected Error Code, recieved" + opContext.LastResult.ExtendedErrorInformation.ErrorCode); + Assert.IsTrue(allowedErrorCodes.Contains(opContext.LastResult.ExtendedErrorInformation.ErrorCode), "Unexpected Error Code, received " + opContext.LastResult.ExtendedErrorInformation.ErrorCode); if (errorMessageBeginsWith != null) { diff --git a/Test/WindowsDesktop/Properties/AssemblyInfo.cs b/Test/WindowsDesktop/Properties/AssemblyInfo.cs index 38e579185..816b43805 100644 --- a/Test/WindowsDesktop/Properties/AssemblyInfo.cs +++ b/Test/WindowsDesktop/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("3.0.0.0")] -[assembly: AssemblyFileVersion("3.0.0.0")] +[assembly: AssemblyVersion("3.0.1.0")] +[assembly: AssemblyFileVersion("3.0.1.0")] diff --git a/Test/WindowsPhone/Blob/BlobAnalyticsUnitTests.cs b/Test/WindowsPhone/Blob/BlobAnalyticsUnitTests.cs index 48dd0259a..5dacebdcd 100644 --- a/Test/WindowsPhone/Blob/BlobAnalyticsUnitTests.cs +++ b/Test/WindowsPhone/Blob/BlobAnalyticsUnitTests.cs @@ -344,6 +344,10 @@ private static ServiceProperties DefaultServiceProperties() props.HourMetrics.RetentionDays = null; props.HourMetrics.Version = "1.0"; + props.MinuteMetrics.MetricsLevel = MetricsLevel.None; + props.MinuteMetrics.RetentionDays = null; + props.MinuteMetrics.Version = "1.0"; + props.DefaultServiceVersion = "2013-08-15"; return props; diff --git a/Test/WindowsPhone/Blob/CloudPageBlobTest.cs b/Test/WindowsPhone/Blob/CloudPageBlobTest.cs index d5dec0da8..1ea0da10f 100644 --- a/Test/WindowsPhone/Blob/CloudPageBlobTest.cs +++ b/Test/WindowsPhone/Blob/CloudPageBlobTest.cs @@ -326,7 +326,6 @@ public async Task CloudPageBlobFetchAttributesAsync() Assert.AreEqual(1024, blob2.Properties.Length); Assert.AreEqual(blob.Properties.ETag, blob2.Properties.ETag); Assert.AreEqual(blob.Properties.LastModified, blob2.Properties.LastModified); - Assert.IsNull(blob2.Properties.CacheControl); Assert.IsNull(blob2.Properties.ContentEncoding); Assert.IsNull(blob2.Properties.ContentLanguage); Assert.AreEqual("application/octet-stream", blob2.Properties.ContentType); diff --git a/Test/WindowsPhone/Blob/LeaseTests.cs b/Test/WindowsPhone/Blob/LeaseTests.cs index 5925790b2..0bca48f16 100644 --- a/Test/WindowsPhone/Blob/LeaseTests.cs +++ b/Test/WindowsPhone/Blob/LeaseTests.cs @@ -640,7 +640,9 @@ public async Task BlobAcquireLeaseStateTestsAsync() // Acquire the lease while in available state, make idempotent call await SetAvailableStateAsync(leasedBlob); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); leaseId = await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); + Assert.IsNotNull(leasedBlob.Properties.ETag); leaseId2 = await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); Assert.AreEqual(leaseId, leaseId2); @@ -731,7 +733,9 @@ await TestHelper.ExpectedExceptionAsync( // Renew infinite lease leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedBlob.Properties.ETag); // Renew infinite lease (wrong lease) leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); @@ -877,7 +881,9 @@ await TestHelper.ExpectedExceptionAsync( // Change leased lease, with idempotent change leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); leaseId2 = await leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedBlob.Properties.ETag); leaseId2 = await leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); // Change a leased lease, with same proposed ID but different lease ID @@ -987,7 +993,9 @@ await TestHelper.ExpectedExceptionAsync( // Release lease (right lease) leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedBlob.Properties.ETag); // Release lease in released state (old lease) leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); @@ -1062,7 +1070,9 @@ await TestHelper.ExpectedExceptionAsync( // Break infinite lease (default break time) leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); leaseTime = await leasedBlob.BreakLeaseAsync(null /* default break period */); + Assert.IsNotNull(leasedBlob.Properties.ETag); Assert.AreEqual(TimeSpan.Zero, leaseTime); // Break infinite lease (zero break time) @@ -1223,8 +1233,7 @@ await TestHelper.ExpectedExceptionAsync( expectedStatusCode, expectedErrorCode); - Stream writeStream = await testBlob.OpenWriteAsync(testAccessCondition, null /* options */, operationContext); - Stream stream = writeStream; + Stream stream = await testBlob.OpenWriteAsync(testAccessCondition, null /* options */, operationContext); await TestHelper.ExpectedExceptionAsync( async () => { @@ -1256,8 +1265,7 @@ private async Task BlobWriteExpectLeaseSuccessAsync(CloudBlockBlob testBlob, ICl await testBlob.FetchAttributesAsync(); } - Stream writeStream = await testBlob.OpenWriteAsync(testAccessCondition, null /* options */, null); - Stream stream = writeStream; + Stream stream = await testBlob.OpenWriteAsync(testAccessCondition, null /* options */, null); stream.WriteByte(0); await stream.FlushAsync(); @@ -1353,8 +1361,7 @@ private async Task BlobReadExpectLeaseSuccessAsync(CloudBlockBlob testBlob, Acce await (await testBlob.CreateSnapshotAsync(null /* metadata */, testAccessCondition, null /* options */, null)).DeleteAsync(); await DownloadTextAsync(testBlob, Encoding.UTF8, testAccessCondition, null /* options */, null); - Stream readStream = await testBlob.OpenReadAsync(testAccessCondition, null /* options */, null); - Stream stream = readStream; + Stream stream = await testBlob.OpenReadAsync(testAccessCondition, null /* options */, null); stream.ReadByte(); } @@ -2188,7 +2195,9 @@ public async Task ContainerAcquireLeaseStateTestsAsync() // Acquire the lease while in available state, make idempotent call await SetUnleasedStateAsync(leasedContainer); + leasedContainer = this.GetContainerReference("lease-tests"); leaseId = await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); + Assert.IsNotNull(leasedContainer.Properties.ETag); leaseId2 = await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); Assert.AreEqual(leaseId, leaseId2); @@ -2279,7 +2288,9 @@ await TestHelper.ExpectedExceptionAsync( // Renew infinite lease leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedContainer.Properties.ETag); // Renew infinite lease (wrong lease) leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); @@ -2420,7 +2431,9 @@ await TestHelper.ExpectedExceptionAsync( // Change leased lease, with idempotent change leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); leaseId2 = await leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedContainer.Properties.ETag); leaseId2 = await leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); // Change a leased lease, with same proposed ID but different lease ID @@ -2530,7 +2543,9 @@ await TestHelper.ExpectedExceptionAsync( // Release lease (right lease) leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedContainer.Properties.ETag); // Release lease in released state (old lease) leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); @@ -2605,7 +2620,9 @@ await TestHelper.ExpectedExceptionAsync( // Break infinite lease (default break time) leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); leaseTime = await leasedContainer.BreakLeaseAsync(null /* default break period */); + Assert.IsNotNull(leasedContainer.Properties.ETag); Assert.AreEqual(TimeSpan.Zero, leaseTime); // Break infinite lease (zero break time) diff --git a/Test/WindowsPhone/Properties/AssemblyInfo.cs b/Test/WindowsPhone/Properties/AssemblyInfo.cs index 01221547c..92bacb117 100644 --- a/Test/WindowsPhone/Properties/AssemblyInfo.cs +++ b/Test/WindowsPhone/Properties/AssemblyInfo.cs @@ -32,6 +32,6 @@ // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("3.0.0.0")] -[assembly: AssemblyFileVersion("3.0.0.0")] +[assembly: AssemblyVersion("3.0.1.0")] +[assembly: AssemblyFileVersion("3.0.1.0")] [assembly: NeutralResourcesLanguageAttribute("en-US")] diff --git a/Test/WindowsPhone/Queue/QueueAnalyticsUnitTests.cs b/Test/WindowsPhone/Queue/QueueAnalyticsUnitTests.cs index f921dd7c3..d8550e841 100644 --- a/Test/WindowsPhone/Queue/QueueAnalyticsUnitTests.cs +++ b/Test/WindowsPhone/Queue/QueueAnalyticsUnitTests.cs @@ -334,6 +334,10 @@ private static ServiceProperties DefaultServiceProperties() props.HourMetrics.RetentionDays = null; props.HourMetrics.Version = "1.0"; + props.MinuteMetrics.MetricsLevel = MetricsLevel.None; + props.MinuteMetrics.RetentionDays = null; + props.MinuteMetrics.Version = "1.0"; + return props; } #endregion diff --git a/Test/WindowsPhone/Table/CloudTableClientTaskTest.cs b/Test/WindowsPhone/Table/CloudTableClientTaskTest.cs index 250f242eb..2a4e991db 100644 --- a/Test/WindowsPhone/Table/CloudTableClientTaskTest.cs +++ b/Test/WindowsPhone/Table/CloudTableClientTaskTest.cs @@ -166,17 +166,8 @@ private async Task DoListTablesSegmentedBasicAsync(TablePayloadFormat format) [TestCategory(SmokeTestCategory.NonSmoke)] [TestCategory(TenantTypeCategory.DevStore), TestCategory(TenantTypeCategory.DevFabric), TestCategory(TenantTypeCategory.Cloud)] public async Task ListTablesSegmentedMaxResultsAsync() - { - await DoListTablesSegmentedMaxResultsAsync(TablePayloadFormat.Json); - await DoListTablesSegmentedMaxResultsAsync(TablePayloadFormat.JsonNoMetadata); - await DoListTablesSegmentedMaxResultsAsync(TablePayloadFormat.JsonFullMetadata); - await DoListTablesSegmentedMaxResultsAsync(TablePayloadFormat.AtomPub); - } - - private async Task DoListTablesSegmentedMaxResultsAsync(TablePayloadFormat format) { CloudTableClient tableClient = GenerateCloudTableClient(); - tableClient.PayloadFormat = format; TableResultSegment segment = null; List totalResults = new List(); diff --git a/Test/WindowsPhone/Table/TableAnalyticsUnitTaskTests.cs b/Test/WindowsPhone/Table/TableAnalyticsUnitTaskTests.cs index 1e67194fc..edc48f2eb 100644 --- a/Test/WindowsPhone/Table/TableAnalyticsUnitTaskTests.cs +++ b/Test/WindowsPhone/Table/TableAnalyticsUnitTaskTests.cs @@ -321,6 +321,10 @@ private static ServiceProperties DefaultServiceProperties() props.HourMetrics.RetentionDays = null; props.HourMetrics.Version = "1.0"; + props.MinuteMetrics.MetricsLevel = MetricsLevel.None; + props.MinuteMetrics.RetentionDays = null; + props.MinuteMetrics.Version = "1.0"; + return props; } #endregion diff --git a/Test/WindowsPhone/Table/TableOperationUnitTaskTests.cs b/Test/WindowsPhone/Table/TableOperationUnitTaskTests.cs index a8e3c35ee..33d291bb1 100644 --- a/Test/WindowsPhone/Table/TableOperationUnitTaskTests.cs +++ b/Test/WindowsPhone/Table/TableOperationUnitTaskTests.cs @@ -154,10 +154,10 @@ private async Task DoTableOperationInsertWithEchoContentAsync(TablePayloadFormat insertResult = await currentTable.ExecuteAsync(TableOperation.Insert(ent, true)); Assert.AreEqual(HttpStatusCode.Created, (HttpStatusCode)insertResult.HttpStatusCode); - // Default is true. + // Default is false. ent = new DynamicTableEntity() { PartitionKey = Guid.NewGuid().ToString(), RowKey = DateTime.Now.Ticks.ToString() }; insertResult = await currentTable.ExecuteAsync(TableOperation.Insert(ent)); - Assert.AreEqual(HttpStatusCode.Created, (HttpStatusCode)insertResult.HttpStatusCode); + Assert.AreEqual(HttpStatusCode.NoContent, (HttpStatusCode)insertResult.HttpStatusCode); } [TestMethod] diff --git a/Test/WindowsRuntime/Blob/CloudBlobClientTest.cs b/Test/WindowsRuntime/Blob/CloudBlobClientTest.cs index 27c968ed2..c9e13349e 100644 --- a/Test/WindowsRuntime/Blob/CloudBlobClientTest.cs +++ b/Test/WindowsRuntime/Blob/CloudBlobClientTest.cs @@ -17,6 +17,7 @@ using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using Microsoft.WindowsAzure.Storage.Auth; +using Microsoft.WindowsAzure.Storage.RetryPolicies; using System; using System.Collections.Generic; using System.IO; @@ -466,6 +467,7 @@ public async Task CloudBlobClientGetServiceStatsAsync() AssertSecondaryEndpoint(); CloudBlobClient client = GenerateCloudBlobClient(); + client.LocationMode = LocationMode.SecondaryOnly; TestHelper.VerifyServiceStats(await client.GetServiceStatsAsync()); } } diff --git a/Test/WindowsRuntime/Blob/LeaseTests.cs b/Test/WindowsRuntime/Blob/LeaseTests.cs index 6ea1bcadd..374cfda1c 100644 --- a/Test/WindowsRuntime/Blob/LeaseTests.cs +++ b/Test/WindowsRuntime/Blob/LeaseTests.cs @@ -640,7 +640,9 @@ public async Task BlobAcquireLeaseStateTestsAsync() // Acquire the lease while in available state, make idempotent call await SetAvailableStateAsync(leasedBlob); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); leaseId = await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); + Assert.IsNotNull(leasedBlob.Properties.ETag); leaseId2 = await leasedBlob.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); Assert.AreEqual(leaseId, leaseId2); @@ -731,7 +733,9 @@ await TestHelper.ExpectedExceptionAsync( // Renew infinite lease leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); await leasedBlob.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedBlob.Properties.ETag); // Renew infinite lease (wrong lease) leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); @@ -877,7 +881,9 @@ await TestHelper.ExpectedExceptionAsync( // Change leased lease, with idempotent change leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); leaseId2 = await leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedBlob.Properties.ETag); leaseId2 = await leasedBlob.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); // Change a leased lease, with same proposed ID but different lease ID @@ -987,7 +993,9 @@ await TestHelper.ExpectedExceptionAsync( // Release lease (right lease) leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); await leasedBlob.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedBlob.Properties.ETag); // Release lease in released state (old lease) leaseId = await SetReleasedStateAsync(leasedBlob, null /* infinite lease */); @@ -1062,7 +1070,9 @@ await TestHelper.ExpectedExceptionAsync( // Break infinite lease (default break time) leaseId = await SetLeasedStateAsync(leasedBlob, null /* infinite lease */); + leasedBlob = this.GetContainerReference("lease-tests").GetBlockBlobReference("LeasedBlob"); leaseTime = await leasedBlob.BreakLeaseAsync(null /* default break period */); + Assert.IsNotNull(leasedBlob.Properties.ETag); Assert.AreEqual(TimeSpan.Zero, leaseTime); // Break infinite lease (zero break time) @@ -2188,7 +2198,9 @@ public async Task ContainerAcquireLeaseStateTestsAsync() // Acquire the lease while in available state, make idempotent call await SetUnleasedStateAsync(leasedContainer); + leasedContainer = this.GetContainerReference("lease-tests"); leaseId = await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); + Assert.IsNotNull(leasedContainer.Properties.ETag); leaseId2 = await leasedContainer.AcquireLeaseAsync(null /* infinite lease */, proposedLeaseId); Assert.AreEqual(leaseId, leaseId2); @@ -2279,7 +2291,9 @@ await TestHelper.ExpectedExceptionAsync( // Renew infinite lease leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); await leasedContainer.RenewLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedContainer.Properties.ETag); // Renew infinite lease (wrong lease) leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); @@ -2420,7 +2434,9 @@ await TestHelper.ExpectedExceptionAsync( // Change leased lease, with idempotent change leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); leaseId2 = await leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedContainer.Properties.ETag); leaseId2 = await leasedContainer.ChangeLeaseAsync(proposedLeaseId2, AccessCondition.GenerateLeaseCondition(leaseId)); // Change a leased lease, with same proposed ID but different lease ID @@ -2530,7 +2546,9 @@ await TestHelper.ExpectedExceptionAsync( // Release lease (right lease) leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); await leasedContainer.ReleaseLeaseAsync(AccessCondition.GenerateLeaseCondition(leaseId)); + Assert.IsNotNull(leasedContainer.Properties.ETag); // Release lease in released state (old lease) leaseId = await SetReleasedStateAsync(leasedContainer, null /* infinite lease */); @@ -2605,7 +2623,9 @@ await TestHelper.ExpectedExceptionAsync( // Break infinite lease (default break time) leaseId = await SetLeasedStateAsync(leasedContainer, null /* infinite lease */); + leasedContainer = this.GetContainerReference("lease-tests"); leaseTime = await leasedContainer.BreakLeaseAsync(null /* default break period */); + Assert.IsNotNull(leasedContainer.Properties.ETag); Assert.AreEqual(TimeSpan.Zero, leaseTime); // Break infinite lease (zero break time) diff --git a/Test/WindowsRuntime/Core/SecondaryTests.cs b/Test/WindowsRuntime/Core/SecondaryTests.cs index 4511642f7..d0a82ef34 100644 --- a/Test/WindowsRuntime/Core/SecondaryTests.cs +++ b/Test/WindowsRuntime/Core/SecondaryTests.cs @@ -51,22 +51,22 @@ public async Task LocationModeWithMissingUriAsync() RetryPolicy = new NoRetry(), }; - StorageException e = await TestHelper.ExpectedExceptionAsync( + Exception e = await TestHelper.ExpectedExceptionAsync( async () => await container.FetchAttributesAsync(null, options, null), "Request should fail when an URI is not provided for the target location"); - Assert.IsInstanceOfType(e.InnerException, typeof(InvalidOperationException)); + Assert.IsInstanceOfType(e.InnerException.InnerException, typeof(InvalidOperationException)); options.LocationMode = LocationMode.SecondaryThenPrimary; - e = await TestHelper.ExpectedExceptionAsync( + e = await TestHelper.ExpectedExceptionAsync( async () => await container.FetchAttributesAsync(null, options, null), "Request should fail when an URI is not provided for the target location"); - Assert.IsInstanceOfType(e.InnerException, typeof(InvalidOperationException)); + Assert.IsInstanceOfType(e.InnerException.InnerException, typeof(InvalidOperationException)); options.LocationMode = LocationMode.PrimaryThenSecondary; - e = await TestHelper.ExpectedExceptionAsync( + e = await TestHelper.ExpectedExceptionAsync( async () => await container.FetchAttributesAsync(null, options, null), "Request should fail when an URI is not provided for the target location"); - Assert.IsInstanceOfType(e.InnerException, typeof(InvalidOperationException)); + Assert.IsInstanceOfType(e.InnerException.InnerException, typeof(InvalidOperationException)); } [TestMethod] diff --git a/Test/WindowsRuntime/Properties/AssemblyInfo.cs b/Test/WindowsRuntime/Properties/AssemblyInfo.cs index 8ed314370..cf7d48208 100644 --- a/Test/WindowsRuntime/Properties/AssemblyInfo.cs +++ b/Test/WindowsRuntime/Properties/AssemblyInfo.cs @@ -22,5 +22,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("3.0.0.0")] -[assembly: AssemblyFileVersion("3.0.0.0")] +[assembly: AssemblyVersion("3.0.1.0")] +[assembly: AssemblyFileVersion("3.0.1.0")] diff --git a/Test/WindowsRuntime/Queue/CloudQueueClientTest.cs b/Test/WindowsRuntime/Queue/CloudQueueClientTest.cs index 066206e9c..f1f729538 100644 --- a/Test/WindowsRuntime/Queue/CloudQueueClientTest.cs +++ b/Test/WindowsRuntime/Queue/CloudQueueClientTest.cs @@ -17,6 +17,7 @@ using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; using Microsoft.WindowsAzure.Storage.Queue.Protocol; +using Microsoft.WindowsAzure.Storage.RetryPolicies; using System; using System.Collections.Generic; using System.Linq; @@ -195,6 +196,7 @@ public async Task CloudQueueClientGetServiceStatsAsync() AssertSecondaryEndpoint(); CloudQueueClient client = GenerateCloudQueueClient(); + client.LocationMode = LocationMode.SecondaryOnly; TestHelper.VerifyServiceStats(await client.GetServiceStatsAsync()); } } diff --git a/Test/WindowsRuntime/Table/CloudTableClientTest.cs b/Test/WindowsRuntime/Table/CloudTableClientTest.cs index 9523aa334..5cf33f84c 100644 --- a/Test/WindowsRuntime/Table/CloudTableClientTest.cs +++ b/Test/WindowsRuntime/Table/CloudTableClientTest.cs @@ -16,6 +16,7 @@ // ----------------------------------------------------------------------------------------- using Microsoft.VisualStudio.TestPlatform.UnitTestFramework; +using Microsoft.WindowsAzure.Storage.RetryPolicies; using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -255,6 +256,7 @@ public async Task CloudTableClientGetServiceStatsAsync() AssertSecondaryEndpoint(); CloudTableClient client = GenerateCloudTableClient(); + client.LocationMode = LocationMode.SecondaryOnly; TestHelper.VerifyServiceStats(await client.GetServiceStatsAsync()); } } diff --git a/Test/WindowsRuntime/Table/TableBatchOperationTest.cs b/Test/WindowsRuntime/Table/TableBatchOperationTest.cs index efc56918c..7efc25ac7 100644 --- a/Test/WindowsRuntime/Table/TableBatchOperationTest.cs +++ b/Test/WindowsRuntime/Table/TableBatchOperationTest.cs @@ -1216,7 +1216,7 @@ public async Task TableBatchEntityOver1MBShouldThrow() } catch (Exception) { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "EntityTooLarge" }, "The entity is larger than allowed by the Table Service."); + TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "EntityTooLarge" }, "The entity is larger than the maximum allowed size (1MB)."); } } @@ -1247,10 +1247,9 @@ public async Task TableBatchOver4MBShouldThrow() await currentTable.ExecuteBatchAsync(batch, null, opContext); Assert.Fail(); } - catch (Exception) { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "ContentLengthExceeded" }, "The content length for the requested operation has exceeded the limit."); + TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.RequestEntityTooLarge, new string[] { "RequestBodyTooLarge" }, "The request body is too large and exceeds the maximum permissible limit."); } } @@ -1416,7 +1415,7 @@ public async Task TableBatchWithPropertyOver255CharsShouldThrow() catch (Exception) { - TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "PropertyNameTooLong" }, "The property name exceeds the maximum allowed length."); + TestHelper.ValidateResponse(opContext, 1, (int)HttpStatusCode.BadRequest, new string[] { "PropertyNameTooLong" }, "The property name exceeds the maximum allowed length (255)."); } } diff --git a/changelog.txt b/changelog.txt index 85f493ce9..ed5c50fec 100644 --- a/changelog.txt +++ b/changelog.txt @@ -158,3 +158,25 @@ Issues fixed in 2.1.0.2 : Issues fixed in 2.1.0.3 : - All: Registered wait handles are unregistered sooner for more efficient GC. + +Issues fixed in 2.1.0.4 : + + - Tables: Do not send the cast operator in the table query filter string. + +Issues fixed in 3.0.0.0 : + + - All: Support for 2013-08-15 REST version - see here for additional details: http://blogs.msdn.com/b/windowsazurestorage/archive/2013/11/27/windows-azure-storage-release-introducing-cors-json-minute-metrics-and-more.aspx. + - All: Suppress warning for FiddlerCore EntensionAttribute conflict. + - Blobs: Added support for XML serialize/deserialize of BlobContinuationToken. + - Blobs: Added ParallelOperationThreadCount and SingleBlobUploadThresholdInBytes to BlobRequestOptions. + - Queues: QueueContinuationToken is moved to Queue namespace(Microsoft.WindowsAzure.Storage.Queue). + - Tables: Fixed GetHashCode() in EntityProperty to return equal values for binary types. + - Tables (RT): Fixed error parsing for tables. + +Issues fixed in 3.0.1.0 : + + - All (WP): Set the Accept type to application/xml explicitly for Get/SetACL. + - Blobs: LastModified and ETag properties are populated after Lease operations. + - Tables: Added an explicit reference to Microsoft.Data.Services.Client in the Nuget package. + - Tables: Fixed an issue caused by a Json .NET bug that resulted in an error being thrown while parsing a table query response. More details on the bug can be found here: http://james.newtonking.com/archive/2013/11/29/fixing-jarray-getenumerator-method-not-found-bug + - Tables (RT): Fixed continuation tokens for queries and listing operations.