Skip to content

Commit ca89328

Browse files
authored
Intial set-up for llc tests (Azure#23909)
* 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
1 parent c3a879f commit ca89328

File tree

7 files changed

+411
-0
lines changed

7 files changed

+411
-0
lines changed

sdk/core/Azure.Core.Experimental/tests/Azure.Core.Experimental.Tests.csproj

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<TargetFrameworks>$(RequiredTargetFrameworks)</TargetFrameworks>
4+
<IncludeGeneratorSharedCode>true</IncludeGeneratorSharedCode>
45
</PropertyGroup>
56

67
<ItemGroup>
@@ -17,5 +18,15 @@
1718
<ItemGroup>
1819
<Compile Remove="perf/**/*.*" />
1920
</ItemGroup>
21+
22+
<!-- Shared source from Azure.Core -->
23+
<ItemGroup>
24+
<Compile Include="$(AzureCoreSharedSources)ArrayBufferWriter.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
25+
<Compile Include="$(AzureCoreSharedSources)ClientDiagnostics.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
26+
<Compile Include="$(AzureCoreSharedSources)ContentTypeUtilities.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
27+
<Compile Include="$(AzureCoreSharedSources)DiagnosticScope.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
28+
<Compile Include="$(AzureCoreSharedSources)DiagnosticScopeFactory.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
29+
<Compile Include="$(AzureCoreSharedSources)HttpMessageSanitizer.cs" Link="Shared\%(RecursiveDir)\%(Filename)%(Extension)" />
30+
</ItemGroup>
2031

2132
</Project>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#nullable disable
5+
6+
using System.Text.Json;
7+
using Azure.Core;
8+
9+
namespace Azure.Core.Experimental.Tests.Models
10+
{
11+
public partial class Pet : IUtf8JsonSerializable
12+
{
13+
void IUtf8JsonSerializable.Write(Utf8JsonWriter writer)
14+
{
15+
writer.WriteStartObject();
16+
17+
writer.WritePropertyName("name");
18+
writer.WriteStringValue(Name);
19+
20+
writer.WritePropertyName("species");
21+
writer.WriteStringValue(Species);
22+
23+
writer.WriteEndObject();
24+
}
25+
26+
internal static Pet DeserializePet(JsonElement element)
27+
{
28+
Optional<string> name = default;
29+
Optional<string> species = default;
30+
foreach (var property in element.EnumerateObject())
31+
{
32+
if (property.NameEquals("name"))
33+
{
34+
name = property.Value.GetString();
35+
continue;
36+
}
37+
if (property.NameEquals("species"))
38+
{
39+
species = property.Value.GetString();
40+
continue;
41+
}
42+
}
43+
return new Pet(name.Value, species.Value);
44+
}
45+
}
46+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#nullable disable
5+
6+
using System;
7+
using System.Text.Json;
8+
9+
namespace Azure.Core.Experimental.Tests.Models
10+
{
11+
/// <summary> The Pet output model. </summary>
12+
public partial class Pet
13+
{
14+
/// <summary> Initializes a new instance of Pet. </summary>
15+
internal Pet()
16+
{
17+
}
18+
19+
/// <summary> Initializes a new instance of Pet. </summary>
20+
/// <param name="id"></param>
21+
/// <param name="name"></param>
22+
/// <param name="species"></param>
23+
internal Pet(string name, string species)
24+
{
25+
Name = name;
26+
Species = species;
27+
}
28+
29+
public string Name { get; }
30+
public string Species { get; }
31+
32+
// Cast from Response to Pet
33+
public static implicit operator Pet(Response response)
34+
{
35+
// [X] TODO: Add in HLC error semantics
36+
// [ ] TODO: Use response.IsError
37+
// [ ] TODO: Use throw new ResponseFailedException(response);
38+
switch (response.Status)
39+
{
40+
case 200:
41+
return DeserializePet(JsonDocument.Parse(response.Content.ToMemory()));
42+
default:
43+
throw new RequestFailedException("Received a non-success status code.");
44+
}
45+
}
46+
47+
private static Pet DeserializePet(JsonDocument document)
48+
{
49+
return new Pet(
50+
document.RootElement.GetProperty("name").GetString(),
51+
document.RootElement.GetProperty("species").GetString());
52+
}
53+
}
54+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System.Text.Json;
5+
using Azure.Core;
6+
7+
namespace Azure.Core.Experimental.Tests.Models
8+
{
9+
internal class SerializationHelpers
10+
{
11+
public delegate void SerializerFunc<in T>(ref Utf8JsonWriter writer, T t);
12+
13+
public static byte[] Serialize<T>(T t, SerializerFunc<T> serializerFunc)
14+
{
15+
var writer = new ArrayBufferWriter<byte>();
16+
var json = new Utf8JsonWriter(writer);
17+
serializerFunc(ref json, t);
18+
json.Flush();
19+
return writer.WrittenMemory.ToArray();
20+
}
21+
}
22+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#nullable disable
5+
6+
using System;
7+
using System.Threading.Tasks;
8+
using Azure;
9+
using Azure.Core;
10+
using Azure.Core.Pipeline;
11+
12+
namespace Azure.Core.Experimental.Tests
13+
{
14+
/// <summary> The PetStore service client. </summary>
15+
public partial class PetStoreClient
16+
{
17+
/// <summary> The HTTP pipeline for sending and receiving REST requests and responses. </summary>
18+
public virtual HttpPipeline Pipeline { get; }
19+
private readonly string[] AuthorizationScopes = { "https://example.azurepetshop.com/.default" };
20+
private readonly TokenCredential _tokenCredential;
21+
private Uri endpoint;
22+
private readonly string apiVersion;
23+
private readonly ClientDiagnostics _clientDiagnostics;
24+
25+
/// <summary> Initializes a new instance of PetStoreClient for mocking. </summary>
26+
protected PetStoreClient()
27+
{
28+
}
29+
30+
/// <summary> Initializes a new instance of PetStoreClient. </summary>
31+
/// <param name="endpoint"> The workspace development endpoint, for example https://myworkspace.dev.azuresynapse.net. </param>
32+
/// <param name="credential"> A credential used to authenticate to an Azure Service. </param>
33+
/// <param name="options"> The options for configuring the client. </param>
34+
public PetStoreClient(Uri endpoint, TokenCredential credential, PetStoreClientOptions options = null)
35+
{
36+
if (endpoint == null)
37+
{
38+
throw new ArgumentNullException(nameof(endpoint));
39+
}
40+
if (credential == null)
41+
{
42+
throw new ArgumentNullException(nameof(credential));
43+
}
44+
45+
options ??= new PetStoreClientOptions();
46+
_clientDiagnostics = new ClientDiagnostics(options);
47+
_tokenCredential = credential;
48+
var authPolicy = new BearerTokenAuthenticationPolicy(_tokenCredential, AuthorizationScopes);
49+
Pipeline = HttpPipelineBuilder.Build(options, new HttpPipelinePolicy[] { new LowLevelCallbackPolicy() }, new HttpPipelinePolicy[] { authPolicy }, new ResponseClassifier());
50+
this.endpoint = endpoint;
51+
apiVersion = options.Version;
52+
}
53+
54+
/// <summary> Get a pet by its Id. </summary>
55+
/// <param name="id"> Id of pet to return. </param>
56+
/// <param name="options"> The request options. </param>
57+
#pragma warning disable AZC0002
58+
public virtual async Task<Response> GetPetAsync(string id, RequestOptions options = null)
59+
#pragma warning restore AZC0002
60+
{
61+
options ??= new RequestOptions();
62+
using HttpMessage message = CreateGetPetRequest(id, options);
63+
RequestOptions.Apply(options, message);
64+
using var scope = _clientDiagnostics.CreateScope("PetStoreClient.GetPet");
65+
scope.Start();
66+
try
67+
{
68+
await Pipeline.SendAsync(message, options.CancellationToken).ConfigureAwait(false);
69+
if (options.StatusOption == ResponseStatusOption.Default)
70+
{
71+
switch (message.Response.Status)
72+
{
73+
case 200:
74+
return message.Response;
75+
default:
76+
throw await _clientDiagnostics.CreateRequestFailedExceptionAsync(message.Response).ConfigureAwait(false);
77+
}
78+
}
79+
else
80+
{
81+
return message.Response;
82+
}
83+
}
84+
catch (Exception e)
85+
{
86+
scope.Failed(e);
87+
throw;
88+
}
89+
}
90+
91+
/// <summary> Get a pet by its Id. </summary>
92+
/// <param name="id"> Id of pet to return. </param>
93+
/// <param name="options"> The request options. </param>
94+
#pragma warning disable AZC0002
95+
public virtual Response GetPet(string id, RequestOptions options = null)
96+
#pragma warning restore AZC0002
97+
{
98+
options ??= new RequestOptions();
99+
using HttpMessage message = CreateGetPetRequest(id, options);
100+
RequestOptions.Apply(options, message);
101+
using var scope = _clientDiagnostics.CreateScope("PetStoreClient.GetPet");
102+
scope.Start();
103+
try
104+
{
105+
Pipeline.Send(message, options.CancellationToken);
106+
if (options.StatusOption == ResponseStatusOption.Default)
107+
{
108+
switch (message.Response.Status)
109+
{
110+
case 200:
111+
return message.Response;
112+
default:
113+
throw _clientDiagnostics.CreateRequestFailedException(message.Response);
114+
}
115+
}
116+
else
117+
{
118+
return message.Response;
119+
}
120+
}
121+
catch (Exception e)
122+
{
123+
scope.Failed(e);
124+
throw;
125+
}
126+
}
127+
128+
/// <summary> Create Request for <see cref="GetPet"/> and <see cref="GetPetAsync"/> operations. </summary>
129+
/// <param name="id"> Id of pet to return. </param>
130+
/// <param name="options"> The request options. </param>
131+
private HttpMessage CreateGetPetRequest(string id, RequestOptions options = null)
132+
{
133+
var message = Pipeline.CreateMessage();
134+
var request = message.Request;
135+
request.Method = RequestMethod.Get;
136+
var uri = new RawRequestUriBuilder();
137+
uri.Reset(endpoint);
138+
uri.AppendPath("/pets/", false);
139+
uri.AppendPath(id, true);
140+
request.Uri = uri;
141+
request.Headers.Add("Accept", "application/json, text/json");
142+
return message;
143+
}
144+
}
145+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
#nullable disable
5+
6+
using System;
7+
using Azure.Core;
8+
9+
namespace Azure.Core.Experimental.Tests
10+
{
11+
/// <summary> Client options for PetStoreClient. </summary>
12+
public partial class PetStoreClientOptions : ClientOptions
13+
{
14+
private const ServiceVersion LatestVersion = ServiceVersion.V2020_12_01;
15+
16+
/// <summary> The version of the service to use. </summary>
17+
public enum ServiceVersion
18+
{
19+
/// <summary> Service version "2020-12-01". </summary>
20+
V2020_12_01 = 1,
21+
}
22+
23+
internal string Version { get; }
24+
25+
/// <summary> Initializes new instance of PetStoreClientOptions. </summary>
26+
public PetStoreClientOptions(ServiceVersion version = LatestVersion)
27+
{
28+
Version = version switch
29+
{
30+
ServiceVersion.V2020_12_01 => "2020-12-01",
31+
_ => throw new NotSupportedException()
32+
};
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)