Skip to content

Commit

Permalink
Intial set-up for llc tests (#23909)
Browse files Browse the repository at this point in the history
* intial set-up for llc tests

* don't generate the code

* saving work in progress

* remove edits to Core

* simplify tests

* implement LLC method with mock transport

* Add in basic model cast functionality, without new Core features
  • Loading branch information
annelo-msft authored Sep 16, 2021
1 parent c3a879f commit ca89328
Show file tree
Hide file tree
Showing 7 changed files with 411 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(RequiredTargetFrameworks)</TargetFrameworks>
<IncludeGeneratorSharedCode>true</IncludeGeneratorSharedCode>
</PropertyGroup>

<ItemGroup>
Expand All @@ -17,5 +18,15 @@
<ItemGroup>
<Compile Remove="perf/**/*.*" />
</ItemGroup>

<!-- Shared source from Azure.Core -->
<ItemGroup>
<Compile Include="$(AzureCoreSharedSources)ArrayBufferWriter.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)ClientDiagnostics.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)ContentTypeUtilities.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)DiagnosticScope.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)DiagnosticScopeFactory.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
<Compile Include="$(AzureCoreSharedSources)HttpMessageSanitizer.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#nullable disable

using System.Text.Json;
using Azure.Core;

namespace Azure.Core.Experimental.Tests.Models
{
public partial class Pet : IUtf8JsonSerializable
{
void IUtf8JsonSerializable.Write(Utf8JsonWriter writer)
{
writer.WriteStartObject();

writer.WritePropertyName("name");
writer.WriteStringValue(Name);

writer.WritePropertyName("species");
writer.WriteStringValue(Species);

writer.WriteEndObject();
}

internal static Pet DeserializePet(JsonElement element)
{
Optional<string> name = default;
Optional<string> species = default;
foreach (var property in element.EnumerateObject())
{
if (property.NameEquals("name"))
{
name = property.Value.GetString();
continue;
}
if (property.NameEquals("species"))
{
species = property.Value.GetString();
continue;
}
}
return new Pet(name.Value, species.Value);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#nullable disable

using System;
using System.Text.Json;

namespace Azure.Core.Experimental.Tests.Models
{
/// <summary> The Pet output model. </summary>
public partial class Pet
{
/// <summary> Initializes a new instance of Pet. </summary>
internal Pet()
{
}

/// <summary> Initializes a new instance of Pet. </summary>
/// <param name="id"></param>
/// <param name="name"></param>
/// <param name="species"></param>
internal Pet(string name, string species)
{
Name = name;
Species = species;
}

public string Name { get; }
public string Species { get; }

// Cast from Response to Pet
public static implicit operator Pet(Response response)
{
// [X] TODO: Add in HLC error semantics
// [ ] TODO: Use response.IsError
// [ ] TODO: Use throw new ResponseFailedException(response);
switch (response.Status)
{
case 200:
return DeserializePet(JsonDocument.Parse(response.Content.ToMemory()));
default:
throw new RequestFailedException("Received a non-success status code.");
}
}

private static Pet DeserializePet(JsonDocument document)
{
return new Pet(
document.RootElement.GetProperty("name").GetString(),
document.RootElement.GetProperty("species").GetString());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System.Text.Json;
using Azure.Core;

namespace Azure.Core.Experimental.Tests.Models
{
internal class SerializationHelpers
{
public delegate void SerializerFunc<in T>(ref Utf8JsonWriter writer, T t);

public static byte[] Serialize<T>(T t, SerializerFunc<T> serializerFunc)
{
var writer = new ArrayBufferWriter<byte>();
var json = new Utf8JsonWriter(writer);
serializerFunc(ref json, t);
json.Flush();
return writer.WrittenMemory.ToArray();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#nullable disable

using System;
using System.Threading.Tasks;
using Azure;
using Azure.Core;
using Azure.Core.Pipeline;

namespace Azure.Core.Experimental.Tests
{
/// <summary> The PetStore service client. </summary>
public partial class PetStoreClient
{
/// <summary> The HTTP pipeline for sending and receiving REST requests and responses. </summary>
public virtual HttpPipeline Pipeline { get; }
private readonly string[] AuthorizationScopes = { "https://example.azurepetshop.com/.default" };
private readonly TokenCredential _tokenCredential;
private Uri endpoint;
private readonly string apiVersion;
private readonly ClientDiagnostics _clientDiagnostics;

/// <summary> Initializes a new instance of PetStoreClient for mocking. </summary>
protected PetStoreClient()
{
}

/// <summary> Initializes a new instance of PetStoreClient. </summary>
/// <param name="endpoint"> The workspace development endpoint, for example https://myworkspace.dev.azuresynapse.net. </param>
/// <param name="credential"> A credential used to authenticate to an Azure Service. </param>
/// <param name="options"> The options for configuring the client. </param>
public PetStoreClient(Uri endpoint, TokenCredential credential, PetStoreClientOptions options = null)
{
if (endpoint == null)
{
throw new ArgumentNullException(nameof(endpoint));
}
if (credential == null)
{
throw new ArgumentNullException(nameof(credential));
}

options ??= new PetStoreClientOptions();
_clientDiagnostics = new ClientDiagnostics(options);
_tokenCredential = credential;
var authPolicy = new BearerTokenAuthenticationPolicy(_tokenCredential, AuthorizationScopes);
Pipeline = HttpPipelineBuilder.Build(options, new HttpPipelinePolicy[] { new LowLevelCallbackPolicy() }, new HttpPipelinePolicy[] { authPolicy }, new ResponseClassifier());
this.endpoint = endpoint;
apiVersion = options.Version;
}

/// <summary> Get a pet by its Id. </summary>
/// <param name="id"> Id of pet to return. </param>
/// <param name="options"> The request options. </param>
#pragma warning disable AZC0002
public virtual async Task<Response> GetPetAsync(string id, RequestOptions options = null)
#pragma warning restore AZC0002
{
options ??= new RequestOptions();
using HttpMessage message = CreateGetPetRequest(id, options);
RequestOptions.Apply(options, message);
using var scope = _clientDiagnostics.CreateScope("PetStoreClient.GetPet");
scope.Start();
try
{
await Pipeline.SendAsync(message, options.CancellationToken).ConfigureAwait(false);
if (options.StatusOption == ResponseStatusOption.Default)
{
switch (message.Response.Status)
{
case 200:
return message.Response;
default:
throw await _clientDiagnostics.CreateRequestFailedExceptionAsync(message.Response).ConfigureAwait(false);
}
}
else
{
return message.Response;
}
}
catch (Exception e)
{
scope.Failed(e);
throw;
}
}

/// <summary> Get a pet by its Id. </summary>
/// <param name="id"> Id of pet to return. </param>
/// <param name="options"> The request options. </param>
#pragma warning disable AZC0002
public virtual Response GetPet(string id, RequestOptions options = null)
#pragma warning restore AZC0002
{
options ??= new RequestOptions();
using HttpMessage message = CreateGetPetRequest(id, options);
RequestOptions.Apply(options, message);
using var scope = _clientDiagnostics.CreateScope("PetStoreClient.GetPet");
scope.Start();
try
{
Pipeline.Send(message, options.CancellationToken);
if (options.StatusOption == ResponseStatusOption.Default)
{
switch (message.Response.Status)
{
case 200:
return message.Response;
default:
throw _clientDiagnostics.CreateRequestFailedException(message.Response);
}
}
else
{
return message.Response;
}
}
catch (Exception e)
{
scope.Failed(e);
throw;
}
}

/// <summary> Create Request for <see cref="GetPet"/> and <see cref="GetPetAsync"/> operations. </summary>
/// <param name="id"> Id of pet to return. </param>
/// <param name="options"> The request options. </param>
private HttpMessage CreateGetPetRequest(string id, RequestOptions options = null)
{
var message = Pipeline.CreateMessage();
var request = message.Request;
request.Method = RequestMethod.Get;
var uri = new RawRequestUriBuilder();
uri.Reset(endpoint);
uri.AppendPath("/pets/", false);
uri.AppendPath(id, true);
request.Uri = uri;
request.Headers.Add("Accept", "application/json, text/json");
return message;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#nullable disable

using System;
using Azure.Core;

namespace Azure.Core.Experimental.Tests
{
/// <summary> Client options for PetStoreClient. </summary>
public partial class PetStoreClientOptions : ClientOptions
{
private const ServiceVersion LatestVersion = ServiceVersion.V2020_12_01;

/// <summary> The version of the service to use. </summary>
public enum ServiceVersion
{
/// <summary> Service version "2020-12-01". </summary>
V2020_12_01 = 1,
}

internal string Version { get; }

/// <summary> Initializes new instance of PetStoreClientOptions. </summary>
public PetStoreClientOptions(ServiceVersion version = LatestVersion)
{
Version = version switch
{
ServiceVersion.V2020_12_01 => "2020-12-01",
_ => throw new NotSupportedException()
};
}
}
}
Loading

0 comments on commit ca89328

Please sign in to comment.