Skip to content

Commit 74607f8

Browse files
authored
Allow specifying default versions on ClientTestFixture (Azure#19431)
1 parent 07d4282 commit 74607f8

File tree

7 files changed

+190
-13
lines changed

7 files changed

+190
-13
lines changed

sdk/core/Azure.Core.TestFramework/src/ClientTestFixtureAttribute.cs

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,18 @@ public class ClientTestFixtureAttribute : NUnitAttribute, IFixtureBuilder2, IPre
2525

2626
private readonly object[] _additionalParameters;
2727
private readonly object[] _serviceVersions;
28-
private readonly int? _maxServiceVersion;
28+
private int? _actualPlaybackServiceVersion;
29+
private int[] _actualLiveServiceVersions;
30+
31+
/// <summary>
32+
/// Specifies which service version is run during recording/playback runs.
33+
/// </summary>
34+
public object RecordingServiceVersion { get; set; }
35+
36+
/// <summary>
37+
/// Specifies which service version is run during live runs.
38+
/// </summary>
39+
public object[] LiveServiceVersions { get; set; }
2940

3041
/// <summary>
3142
/// Initializes an instance of the <see cref="ClientTestFixtureAttribute"/> accepting additional fixture parameters.
@@ -43,8 +54,6 @@ public ClientTestFixtureAttribute(object[] serviceVersions, object[] additionalP
4354
{
4455
_additionalParameters = additionalParameters ?? new object[] { };
4556
_serviceVersions = serviceVersions ?? new object[] { };
46-
47-
_maxServiceVersion = _serviceVersions.Any() ? _serviceVersions.Max(s => Convert.ToInt32(s)) : (int?)null;
4857
}
4958

5059
public IEnumerable<TestSuite> BuildFrom(ITypeInfo typeInfo)
@@ -54,6 +63,23 @@ public IEnumerable<TestSuite> BuildFrom(ITypeInfo typeInfo)
5463

5564
public IEnumerable<TestSuite> BuildFrom(ITypeInfo typeInfo, IPreFilter filter)
5665
{
66+
var latestVersion = _serviceVersions.Any() ? _serviceVersions.Max(Convert.ToInt32) : (int?)null;
67+
_actualPlaybackServiceVersion = RecordingServiceVersion != null ? Convert.ToInt32(RecordingServiceVersion) : latestVersion;
68+
69+
var liveVersions = LiveServiceVersions ?? _serviceVersions;
70+
71+
if (liveVersions.Any())
72+
{
73+
if (OnlyTestLatestServiceVersionLazy.Value)
74+
{
75+
_actualLiveServiceVersions = new[] { liveVersions.Max(Convert.ToInt32) };
76+
}
77+
else
78+
{
79+
_actualLiveServiceVersions = liveVersions.Select(Convert.ToInt32).ToArray();
80+
}
81+
}
82+
5783
var suitePermutations = GeneratePermutations();
5884

5985
foreach (var (fixture, isAsync, serviceVersion, parameter) in suitePermutations)
@@ -114,6 +140,8 @@ public IEnumerable<TestSuite> BuildFrom(ITypeInfo typeInfo, IPreFilter filter)
114140
private void Process(TestSuite testSuite, object serviceVersion, bool isAsync, object parameter)
115141
{
116142
var serviceVersionNumber = Convert.ToInt32(serviceVersion);
143+
ApplyLimits(serviceVersionNumber, testSuite);
144+
117145
foreach (Test test in testSuite.Tests)
118146
{
119147
if (test is ParameterizedMethodSuite parameterizedMethodSuite)
@@ -157,18 +185,23 @@ private void ProcessTest(object serviceVersion, bool isAsync, int serviceVersion
157185
return;
158186
}
159187

160-
if (serviceVersionNumber != _maxServiceVersion)
188+
if (serviceVersionNumber != _actualPlaybackServiceVersion)
161189
{
162-
test.Properties.Add("SkipRecordings", $"Test is ignored when not running live because the service version {serviceVersion} is not the latest.");
190+
test.Properties.Add("SkipRecordings", $"Test is ignored when not running live because the service version {serviceVersion} is not {_actualPlaybackServiceVersion}.");
163191
}
164192

165-
if (OnlyTestLatestServiceVersionLazy.Value && serviceVersionNumber != _maxServiceVersion)
193+
if (_actualLiveServiceVersions != null &&
194+
!_actualLiveServiceVersions.Contains(serviceVersionNumber))
166195
{
167-
test.RunState = RunState.Ignored;
168-
test.Properties.Set("_SKIPREASON",
169-
$"Test ignored because {OnlyTestLatestServiceVersionKey} is set in the environment and version {serviceVersion} is not the latest.");
196+
test.Properties.Set("SkipLive",
197+
$"Test ignored when running live service version {serviceVersion} is not one of {string.Join(", " , _actualLiveServiceVersions)}.");
170198
}
171199

200+
ApplyLimits(serviceVersionNumber, test);
201+
}
202+
203+
private static void ApplyLimits(int serviceVersionNumber, Test test)
204+
{
172205
var minServiceVersion = test.GetCustomAttributes<ServiceVersionAttribute>(true);
173206
foreach (ServiceVersionAttribute serviceVersionAttribute in minServiceVersion)
174207
{
@@ -179,7 +212,7 @@ private void ProcessTest(object serviceVersion, bool isAsync, int serviceVersion
179212
test.Properties.Set("_SKIPREASON", $"Test ignored because it's minimum service version is set to {serviceVersionAttribute.Min}");
180213
}
181214

182-
if (serviceVersionAttribute.Max != null &&
215+
if (serviceVersionAttribute.Max != null &
183216
Convert.ToInt32(serviceVersionAttribute.Max) < serviceVersionNumber)
184217
{
185218
test.RunState = RunState.Ignored;

sdk/core/Azure.Core.TestFramework/src/RecordedTestBase.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,13 @@ public virtual void StartTestRecording()
143143
{
144144
throw new IgnoreException((string) test.Properties.Get("SkipRecordings"));
145145
}
146+
147+
if (Mode == RecordedTestMode.Live &&
148+
test.Properties.ContainsKey("SkipLive"))
149+
{
150+
throw new IgnoreException((string) test.Properties.Get("SkipLive"));
151+
}
152+
146153
Recording = new TestRecording(Mode, GetSessionFilePath(), Sanitizer, Matcher);
147154
ValidateClientInstrumentation = Recording.HasRequests;
148155
}

sdk/core/Azure.Core.TestFramework/src/ServiceVersionAttribute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace Azure.Core.TestFramework
88
{
9-
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
9+
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
1010
public class ServiceVersionAttribute : NUnitAttribute
1111
{
1212
public object Min { get; set; }

sdk/core/Azure.Core/tests/ClientTestBaseMultiVersionTests.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
namespace Azure.Core.Tests
88
{
9-
[ClientTestFixture(FakeClientVersion.V1, FakeClientVersion.V2, FakeClientVersion.V3)]
9+
[ClientTestFixture(FakeClientVersion.V0, FakeClientVersion.V1, FakeClientVersion.V2, FakeClientVersion.V3, FakeClientVersion.V4)]
10+
[ServiceVersion(Min = FakeClientVersion.V1, Max = FakeClientVersion.V3)]
1011
public class ClientTestBaseMultiVersionTests : ClientTestBase
1112
{
1213
private readonly FakeClientVersion _version;
@@ -59,9 +60,11 @@ public void SyncOnlyWorks()
5960

6061
public enum FakeClientVersion
6162
{
63+
V0 = 0,
6264
V1 = 1,
6365
V2 = 2,
64-
V3 = 3
66+
V3 = 3,
67+
V4 = 4
6568
}
6669
}
6770
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
using System;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
using Azure.Core.Pipeline;
8+
using Azure.Core.TestFramework;
9+
using NUnit.Framework;
10+
11+
namespace Azure.Core.Tests
12+
{
13+
[ClientTestFixture(
14+
TestClientOptions.ServiceVersion.V0,
15+
TestClientOptions.ServiceVersion.V1,
16+
TestClientOptions.ServiceVersion.V2,
17+
TestClientOptions.ServiceVersion.V3,
18+
RecordingServiceVersion = TestClientOptions.ServiceVersion.V2,
19+
LiveServiceVersions = new object[] { TestClientOptions.ServiceVersion.V1, TestClientOptions.ServiceVersion.V0 })]
20+
public class ClientTestBaseMultiVersionTestsWithSpecificVersions : RecordedTestBase
21+
{
22+
private readonly TestClientOptions.ServiceVersion _version;
23+
24+
public ClientTestBaseMultiVersionTestsWithSpecificVersions(bool isAsync, TestClientOptions.ServiceVersion version) : base(isAsync)
25+
{
26+
_version = version;
27+
TestDiagnostics = false;
28+
}
29+
30+
[Test]
31+
public async Task HasValidVersion()
32+
{
33+
var testClientOptions = new TestClientOptions(_version) { Transport = new MockTransport(new MockResponse(200))};
34+
var client = InstrumentClient(new TestClient(InstrumentClientOptions(testClientOptions)));
35+
await client.GetAsync(default);
36+
if (Mode == RecordedTestMode.Playback || Mode == RecordedTestMode.Record)
37+
{
38+
Assert.IsTrue(_version == TestClientOptions.ServiceVersion.V2);
39+
}
40+
else
41+
{
42+
Assert.IsTrue(_version == TestClientOptions.ServiceVersion.V1 || _version == TestClientOptions.ServiceVersion.V0);
43+
}
44+
}
45+
46+
public class TestClientOptions: ClientOptions
47+
{
48+
public readonly ServiceVersion Version;
49+
50+
public enum ServiceVersion
51+
{
52+
V0 = 0,
53+
V1 = 1,
54+
V2 = 2,
55+
V3 = 3
56+
}
57+
58+
public TestClientOptions(ServiceVersion serviceVersion)
59+
{
60+
Version = serviceVersion;
61+
}
62+
}
63+
public class TestClient
64+
{
65+
private readonly TestClientOptions _options;
66+
private HttpPipeline _pipeline;
67+
68+
protected TestClient(){}
69+
public TestClient(TestClientOptions options)
70+
{
71+
_options = options;
72+
_pipeline = HttpPipelineBuilder.Build(options);
73+
}
74+
75+
public virtual Response Get(CancellationToken cancellationToken)
76+
{
77+
using var request = _pipeline.CreateRequest();
78+
request.Method = RequestMethod.Get;
79+
request.Uri.Reset(new Uri("http://localhost"));
80+
request.Uri.AppendQuery("api", _options.Version.ToString());
81+
return _pipeline.SendRequest(request, cancellationToken);
82+
}
83+
84+
public virtual async Task<Response> GetAsync(CancellationToken cancellationToken)
85+
{
86+
using var request = _pipeline.CreateRequest();
87+
request.Method = RequestMethod.Get;
88+
request.Uri.Reset(new Uri("http://localhost"));
89+
request.Uri.AppendQuery("api", _options.Version.ToString());
90+
return await _pipeline.SendRequestAsync(request, cancellationToken);
91+
}
92+
}
93+
}
94+
}

sdk/core/Azure.Core/tests/SessionRecords/ClientTestBaseMultiVersionTestsWithSpecificVersions/HasValidVersion.json

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/core/Azure.Core/tests/SessionRecords/ClientTestBaseMultiVersionTestsWithSpecificVersions/HasValidVersionAsync.json

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)