Skip to content

Commit

Permalink
Avoid serializing and deserializing template specs (#6833)
Browse files Browse the repository at this point in the history
  • Loading branch information
shenglol authored May 12, 2022
1 parent 2d37ef2 commit 46dd19e
Show file tree
Hide file tree
Showing 11 changed files with 61 additions and 322 deletions.
6 changes: 1 addition & 5 deletions src/Bicep.Core.Samples/DataSetsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using Bicep.Core.Analyzers.Linter;
using Bicep.Core.Configuration;
using Bicep.Core.FileSystem;
using Bicep.Core.Json;
using Bicep.Core.Modules;
using Bicep.Core.Registry;
using Bicep.Core.Semantics;
Expand Down Expand Up @@ -112,13 +111,10 @@ public static ITemplateSpecRepositoryFactory CreateMockTemplateSpecRepositoryFac
throw new InvalidOperationException($"Module '{moduleName}' has an invalid target reference '{templateSpecInfo.Metadata.Target}'. Specify a reference to a template spec.");
}

var templateSpecElement = JsonElementFactory.CreateElement(templateSpecInfo.ModuleSource);
var templateSpecEntity = TemplateSpecEntity.FromJsonElement(templateSpecElement);

repositoryMocksBySubscription.TryAdd(reference.SubscriptionId, StrictMock.Of<ITemplateSpecRepository>());
repositoryMocksBySubscription[reference.SubscriptionId]
.Setup(x => x.FindTemplateSpecByIdAsync(reference.TemplateSpecResourceId, It.IsAny<CancellationToken>()))
.ReturnsAsync(templateSpecEntity);
.ReturnsAsync(new TemplateSpecEntity(templateSpecInfo.ModuleSource));
}

var repositoryFactoryMock = StrictMock.Of<ITemplateSpecRepositoryFactory>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the MIT License.

using System.Linq;
using Azure.Deployments.Core.Extensions;
using Bicep.Core.Analyzers.Linter.Rules;
using Microsoft.VisualStudio.TestTools.UnitTesting;

Expand Down
96 changes: 50 additions & 46 deletions src/Bicep.Core.UnitTests/Registry/TemplateSpecRepositoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
// Licensed under the MIT License.

using System;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Azure;
using Azure.Core;
using Azure.ResourceManager;
using Azure.ResourceManager.Resources;
using Bicep.Core.Registry;
Expand All @@ -25,14 +25,14 @@ public class TemplateSpecRepositoryTests
[TestMethod]
public async Task FindTemplateSpecByIdAsync_TemplateSpecNotFound_ThrowsTemplateSpecException()
{
var templateSpecVersionMock = CreateMockTemplateSpecVersion(templateSpecVersionMock => templateSpecVersionMock
.Setup(x => x.GetAsync(It.IsAny<CancellationToken>()))
.ThrowsAsync(new RequestFailedException(404, "Not found.")));
var templateSpecVersionResourceMock = CreateMockTemplateSpecVersionResource(
mock => mock
.Setup(x => x.GetAsync(It.IsAny<CancellationToken>()))
.ThrowsAsync(new RequestFailedException(404, "Not found.")));

var clientMock = CreateMockClient();
var templateSpecVersionProviderMock = CreateMockTemplateSpecVersionProvider(clientMock, templateSpecVersionMock);
var clientMock = CreateMockClient(templateSpecVersionResourceMock);

var repository = new TemplateSpecRepository(clientMock, templateSpecVersionProviderMock);
var repository = new TemplateSpecRepository(clientMock);

await Invoking(async () => await repository.FindTemplateSpecByIdAsync(TestTemplateSpecId))
.Should()
Expand All @@ -43,14 +43,13 @@ await Invoking(async () => await repository.FindTemplateSpecByIdAsync(TestTempla
[TestMethod]
public async Task FindTemplateSpecByIdAsync_GotUnexpectedRequestFailedException_ConvertsToTemplateSpecException()
{
var templateSpecVersionMock = CreateMockTemplateSpecVersion(templateSpecVersionMock => templateSpecVersionMock
.Setup(x => x.GetAsync(It.IsAny<CancellationToken>()))
.ThrowsAsync(new RequestFailedException("Unexpected error.")));
var templateSpecVersionResourceMock = CreateMockTemplateSpecVersionResource(mock =>
mock.Setup(x => x.GetAsync(It.IsAny<CancellationToken>()))
.ThrowsAsync(new RequestFailedException("Unexpected error.")));

var clientMock = CreateMockClient();
var templateSpecVersionProviderMock = CreateMockTemplateSpecVersionProvider(clientMock, templateSpecVersionMock);
var clientMock = CreateMockClient(templateSpecVersionResourceMock);

var repository = new TemplateSpecRepository(clientMock, templateSpecVersionProviderMock);
var repository = new TemplateSpecRepository(clientMock);

await Invoking(async () => await repository.FindTemplateSpecByIdAsync(TestTemplateSpecId))
.Should()
Expand All @@ -61,42 +60,42 @@ await Invoking(async () => await repository.FindTemplateSpecByIdAsync(TestTempla
[TestMethod]
public async Task FindTemplateSpecByIdAsync_TemlateSpecFound_ReturnsTemplateSpec()
{
var data = new TemplateSpecVersionData("westus")
{
MainTemplate = new BinaryData("{}")
};

var templateSpecVersionMock = CreateMockTemplateSpecVersion(
templateSpecVersionMock => templateSpecVersionMock
.SetupGet(x => x.Data)
.Returns(data),
templateSpecVersionMock => templateSpecVersionMock
var data = new TemplateSpecVersionData("westus");
var content = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true });

var templateSpecVersionResourceMock = CreateMockTemplateSpecVersionResource(
mock => mock
.Setup(x => x.GetAsync(It.IsAny<CancellationToken>()))
.ReturnsAsync(CreateMockResponse(templateSpecVersionMock.Object)));
.ReturnsAsync(CreateMockResponse(content)));

var clientMock = CreateMockClient();
var templateSpecVersionProviderMock = CreateMockTemplateSpecVersionProvider(clientMock, templateSpecVersionMock);
var clientMock = CreateMockClient(templateSpecVersionResourceMock);

var repository = new TemplateSpecRepository(clientMock, templateSpecVersionProviderMock);
var repository = new TemplateSpecRepository(clientMock);

var templateSpec = await repository.FindTemplateSpecByIdAsync(TestTemplateSpecId);

templateSpec.MainTemplate.GetRawText().Should().Be("{}");
templateSpec.Content.ReplaceLineEndings().Should().Be(@"{
""Location"": {
""Name"": ""westus"",
""DisplayName"": ""West US""
},
""Tags"": {},
""Description"": null,
""LinkedTemplates"": [],
""Metadata"": null,
""MainTemplate"": null,
""UiFormDefinition"": null,
""Id"": null,
""Name"": null,
""ResourceType"": {
""Namespace"": null,
""Type"": null
},
""SystemData"": null
}".ReplaceLineEndings());
}

private ITemplateSpecVersionProvider CreateMockTemplateSpecVersionProvider(
ArmClient armClient,
TemplateSpecVersionResource templateSpecVersion)
{
var templateSpecVersionProvider = StrictMock.Of<ITemplateSpecVersionProvider>();
templateSpecVersionProvider
.Setup(x => x.GetTemplateSpecVersion(armClient, It.IsAny<ResourceIdentifier>()))
.Returns(templateSpecVersion);

return templateSpecVersionProvider.Object;
}

private static TemplateSpecVersionResource CreateMockTemplateSpecVersion(params Action<Mock<TemplateSpecVersionResource>>[] setUpTemplateSpecVersionMockActions)
private static TemplateSpecVersionResource CreateMockTemplateSpecVersionResource(params Action<Mock<TemplateSpecVersionResource>>[] setUpTemplateSpecVersionMockActions)
{
var templateSpecVersionMock = StrictMock.Of<TemplateSpecVersionResource>();

Expand All @@ -108,18 +107,23 @@ private static TemplateSpecVersionResource CreateMockTemplateSpecVersion(params
return templateSpecVersionMock.Object;
}

private static ArmClient CreateMockClient()
private static ArmClient CreateMockClient(TemplateSpecVersionResource resource)
{
var clientMock = StrictMock.Of<ArmClient>();

clientMock.Setup(x => x.GetResourceClient(It.IsAny<Func<TemplateSpecVersionResource>>()))
.Returns(resource);

return clientMock.Object;
}

private static Response<T> CreateMockResponse<T>(T value)
private static Response<TemplateSpecVersionResource> CreateMockResponse(string content)
{
var responseMock = StrictMock.Of<Response<T>>();
responseMock.SetupGet(m => m.Value).Returns(value);
responseMock.Setup(m => m.GetRawResponse()).Returns(StrictMock.Of<Response>().Object);
var rawResponseMock = StrictMock.Of<Response>();
rawResponseMock.SetupGet(x => x.Content).Returns(BinaryData.FromString(content));

var responseMock = StrictMock.Of<Response<TemplateSpecVersionResource>>();
responseMock.Setup(m => m.GetRawResponse()).Returns(rawResponseMock.Object);

return responseMock.Object;
}
Expand Down
1 change: 0 additions & 1 deletion src/Bicep.Core/Registry/ExternalModuleRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ namespace Bicep.Core.Registry
{
public abstract class ExternalModuleRegistry<TModuleReference, TModuleEntity> : ModuleRegistry<TModuleReference>
where TModuleReference : ModuleReference
where TModuleEntity : class
{
// if we're unable to acquire a lock on the module directory in the cache, we will retry until this timeout is reached
private static readonly TimeSpan ModuleDirectoryContentionTimeout = TimeSpan.FromSeconds(5);
Expand Down
14 changes: 0 additions & 14 deletions src/Bicep.Core/Registry/ITemplateSpecVersionProvider.cs

This file was deleted.

Loading

0 comments on commit 46dd19e

Please sign in to comment.