Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provider restore for resource type providers #11458

Merged
merged 13 commits into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
340 changes: 219 additions & 121 deletions src/Bicep.Cli.IntegrationTests/BuildCommandTests.cs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/Bicep.Cli.IntegrationTests/RestoreCommandTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public async Task Restore_ArtifactWithoutArtifactType_ShouldSucceed()

using (var compiledStream = new BufferedMemoryStream())
{
OciArtifactModuleReference.TryParse(null, $"{registry}/{repository}:v1", configuration, new Uri("file:///main.bicep"), out var moduleReference, out _).Should().BeTrue();
OciModuleReference.TryParse(null, $"{registry}/{repository}:v1", configuration, new Uri("file:///main.bicep"), out var moduleReference, out _).Should().BeTrue();

compiledStream.Write(TemplateEmitter.UTF8EncodingWithoutBom.GetBytes(dataSet.Compiled!));
compiledStream.Position = 0;
Expand Down
2 changes: 0 additions & 2 deletions src/Bicep.Cli/Commands/PublishCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@
using Bicep.Core.Exceptions;
using Bicep.Core.FileSystem;
using Bicep.Core.Modules;
using Bicep.Core.Parsing;
using Bicep.Core.Registry;
using System;
using System.Data.Common;
using System.IO;
using System.IO.Abstractions;
using System.Threading.Tasks;
Expand Down
11 changes: 7 additions & 4 deletions src/Bicep.Cli/Services/CompilationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public async Task RestoreAsync(string inputPath, bool forceModulesRestore)
var configuration = this.configurationManager.GetConfiguration(inputUri);

var compilation = await bicepCompiler.CreateCompilation(inputUri, this.workspace, skipRestore: true, forceModulesRestore: forceModulesRestore);
var originalModulesToRestore = compilation.SourceFileGrouping.GetModulesToRestore().ToImmutableHashSet();
var originalModulesToRestore = compilation.SourceFileGrouping.GetArtifactsToRestore().ToImmutableHashSet();

// RestoreModules() does a distinct but we'll do it also to prevent duplicates in processing and logging
var modulesToRestoreReferences = this.moduleDispatcher.GetValidModuleReferences(originalModulesToRestore)
Expand Down Expand Up @@ -131,16 +131,19 @@ public DecompileResult DecompileParams(string inputPath, string outputPath, stri
return decompilation;
}

private static ImmutableDictionary<BicepSourceFile, ImmutableArray<IDiagnostic>> GetModuleRestoreDiagnosticsByBicepFile(SourceFileGrouping sourceFileGrouping, ImmutableHashSet<ModuleSourceResolutionInfo> originalModulesToRestore, bool forceModulesRestore)
private static ImmutableDictionary<BicepSourceFile, ImmutableArray<IDiagnostic>> GetModuleRestoreDiagnosticsByBicepFile(SourceFileGrouping sourceFileGrouping, ImmutableHashSet<IArtifactResolutionInfo> originalModulesToRestore, bool forceModulesRestore)
{
static IDiagnostic? DiagnosticForModule(SourceFileGrouping grouping, IForeignTemplateReference module)
=> grouping.TryGetErrorDiagnostic(module) is { } errorBuilder ? errorBuilder(DiagnosticBuilder.ForPosition(module.ReferenceSourceSyntax)) : null;

static IEnumerable<(BicepFile, IDiagnostic)> GetDiagnosticsForModulesToRestore(SourceFileGrouping grouping, ImmutableHashSet<ModuleSourceResolutionInfo> originalModulesToRestore)
static IEnumerable<(BicepFile, IDiagnostic)> GetDiagnosticsForModulesToRestore(SourceFileGrouping grouping, ImmutableHashSet<IArtifactResolutionInfo> originalArtifactsToRestore)
{
var originalModulesToRestore = originalArtifactsToRestore.OfType<ModuleSourceResolutionInfo>();
foreach (var (module, sourceFile) in originalModulesToRestore)
{
if (sourceFile is BicepFile bicepFile && DiagnosticForModule(grouping, module) is { } diagnostic)
if (sourceFile is BicepFile bicepFile &&
module is ModuleDeclarationSyntax moduleDeclaration &&
DiagnosticForModule(grouping, moduleDeclaration) is { } diagnostic)
{
yield return (bicepFile, diagnostic);
}
Expand Down
7 changes: 1 addition & 6 deletions src/Bicep.Core.IntegrationTests/Emit/TemplateEmitterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,17 @@
using Bicep.Core.Parsing;
using Bicep.Core.Registry;
using Bicep.Core.Samples;
using Bicep.Core.Semantics;
using Bicep.Core.UnitTests;
using Bicep.Core.UnitTests.Assertions;
using Bicep.Core.UnitTests.Features;
using Bicep.Core.UnitTests.Mock;
using Bicep.Core.UnitTests.Utils;
using Bicep.Core.Workspaces;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using FluentAssertions.Execution;
using Bicep.Core.UnitTests.Baselines;
using System;
using System.Reflection;
using System.Text.RegularExpressions;


namespace Bicep.Core.IntegrationTests.Emit
{
Expand Down
22 changes: 11 additions & 11 deletions src/Bicep.Core.IntegrationTests/RegistryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ public async Task ModuleRestoreContentionShouldProduceConsistentState()
// initially the cache should be empty
foreach (var moduleReference in moduleReferences)
{
dispatcher.GetModuleRestoreStatus(moduleReference, out _).Should().Be(ModuleRestoreStatus.Unknown);
dispatcher.GetModuleRestoreStatus(moduleReference, out _).Should().Be(ArtifactRestoreStatus.Unknown);
}

const int ConcurrentTasks = 50;
Expand All @@ -202,7 +202,7 @@ public async Task ModuleRestoreContentionShouldProduceConsistentState()
// modules should now be in the cache
foreach (var moduleReference in moduleReferences)
{
dispatcher.GetModuleRestoreStatus(moduleReference, out _).Should().Be(ModuleRestoreStatus.Succeeded);
dispatcher.GetModuleRestoreStatus(moduleReference, out _).Should().Be(ArtifactRestoreStatus.Succeeded);
}
}

Expand Down Expand Up @@ -238,7 +238,7 @@ public async Task ModuleRestoreWithStuckFileLockShouldFailAfterTimeout(IEnumerab
// initially the cache should be empty
foreach (var moduleReference in moduleReferences)
{
dispatcher.GetModuleRestoreStatus(moduleReference, out _).Should().Be(ModuleRestoreStatus.Unknown);
dispatcher.GetModuleRestoreStatus(moduleReference, out _).Should().Be(ArtifactRestoreStatus.Unknown);
}

dispatcher.TryGetLocalModuleEntryPointUri(moduleReferences[0], out var moduleFileUri, out _).Should().BeTrue();
Expand All @@ -261,7 +261,7 @@ public async Task ModuleRestoreWithStuckFileLockShouldFailAfterTimeout(IEnumerab
}

// the first module should have failed due to a timeout
dispatcher.GetModuleRestoreStatus(moduleReferences[0], out var failureBuilder).Should().Be(ModuleRestoreStatus.Failed);
dispatcher.GetModuleRestoreStatus(moduleReferences[0], out var failureBuilder).Should().Be(ArtifactRestoreStatus.Failed);
using (new AssertionScope())
{
failureBuilder!.Should().HaveCode("BCP192");
Expand All @@ -271,7 +271,7 @@ public async Task ModuleRestoreWithStuckFileLockShouldFailAfterTimeout(IEnumerab
// all other modules should have succeeded
foreach (var moduleReference in moduleReferences.Skip(1))
{
dispatcher.GetModuleRestoreStatus(moduleReference, out _).Should().Be(ModuleRestoreStatus.Succeeded);
dispatcher.GetModuleRestoreStatus(moduleReference, out _).Should().Be(ArtifactRestoreStatus.Succeeded);
}
}

Expand Down Expand Up @@ -306,7 +306,7 @@ public async Task ForceModuleRestoreWithStuckFileLockShouldFailAfterTimeout(IEnu
// initially the cache should be empty
foreach (var moduleReference in moduleReferences)
{
dispatcher.GetModuleRestoreStatus(moduleReference, out _).Should().Be(ModuleRestoreStatus.Unknown);
dispatcher.GetModuleRestoreStatus(moduleReference, out _).Should().Be(ArtifactRestoreStatus.Unknown);
}

dispatcher.TryGetLocalModuleEntryPointUri(moduleReferences[0], out var moduleFileUri, out _).Should().BeTrue();
Expand All @@ -333,18 +333,18 @@ public async Task ForceModuleRestoreWithStuckFileLockShouldFailAfterTimeout(IEnu
using (new AssertionScope())
{
#if WINDOWS_BUILD
dispatcher.GetModuleRestoreStatus(moduleReferences[0], out var failureBuilder).Should().Be(ModuleRestoreStatus.Failed);
dispatcher.GetModuleRestoreStatus(moduleReferences[0], out var failureBuilder).Should().Be(ArtifactRestoreStatus.Failed);

failureBuilder!.Should().HaveCode("BCP233");
failureBuilder!.Should().HaveMessageStartWith($"Unable to delete the module with reference \"{moduleReferences[0].FullyQualifiedReference}\" from cache: Exceeded the timeout of \"00:00:05\" for the lock on file \"{lockFileUri}\" to be released.");
#else
dispatcher.GetModuleRestoreStatus(moduleReferences[0], out _).Should().Be(ModuleRestoreStatus.Succeeded);
dispatcher.GetModuleRestoreStatus(moduleReferences[0], out _).Should().Be(ArtifactRestoreStatus.Succeeded);
#endif

// all other modules should have succeeded
foreach (var moduleReference in moduleReferences.Skip(1))
{
dispatcher.GetModuleRestoreStatus(moduleReference, out _).Should().Be(ModuleRestoreStatus.Succeeded);
dispatcher.GetModuleRestoreStatus(moduleReference, out _).Should().Be(ArtifactRestoreStatus.Succeeded);
}
}

Expand Down Expand Up @@ -382,7 +382,7 @@ public async Task ForceModuleRestoreShouldRestoreAllModules(IEnumerable<External
// initially the cache should be empty
foreach (var moduleReference in moduleReferences)
{
dispatcher.GetModuleRestoreStatus(moduleReference, out _).Should().Be(ModuleRestoreStatus.Unknown);
dispatcher.GetModuleRestoreStatus(moduleReference, out _).Should().Be(ArtifactRestoreStatus.Unknown);
}

dispatcher.TryGetLocalModuleEntryPointUri(moduleReferences[0], out var moduleFileUri, out _).Should().BeTrue();
Expand All @@ -397,7 +397,7 @@ public async Task ForceModuleRestoreShouldRestoreAllModules(IEnumerable<External
// all other modules should have succeeded
foreach (var moduleReference in moduleReferences)
{
dispatcher.GetModuleRestoreStatus(moduleReference, out _).Should().Be(ModuleRestoreStatus.Succeeded);
dispatcher.GetModuleRestoreStatus(moduleReference, out _).Should().Be(ArtifactRestoreStatus.Succeeded);
}
}

Expand Down
9 changes: 1 addition & 8 deletions src/Bicep.Core.Samples/DataSetsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,16 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Azure.Containers.ContainerRegistry;
using Azure.Identity;
using Bicep.Core.Configuration;
using Bicep.Core.Features;
using Bicep.Core.FileSystem;
using Bicep.Core.Modules;
using Bicep.Core.Registry;
using Bicep.Core.Semantics;
using Bicep.Core.Semantics.Namespaces;
using Bicep.Core.TypeSystem.Az;
using Bicep.Core.UnitTests;
using Bicep.Core.UnitTests.Configuration;
using Bicep.Core.UnitTests.Features;
using Bicep.Core.UnitTests.Mock;
using Bicep.Core.UnitTests.Registry;
using Bicep.Core.UnitTests.Utils;
using Bicep.Core.Workspaces;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
Expand Down Expand Up @@ -72,7 +65,7 @@ public static Mock<IContainerRegistryClientFactory> CreateMockRegistryClients(th
{
var target = publishInfo.Metadata.Target;

if (!dispatcher.TryGetModuleReference(target, RandomFileUri(), out var @ref, out _) || @ref is not OciArtifactModuleReference targetReference)
if (!dispatcher.TryGetModuleReference(target, RandomFileUri(), out var @ref, out _) || @ref is not OciModuleReference targetReference)
{
throw new InvalidOperationException($"Module '{moduleName}' has an invalid target reference '{target}'. Specify a reference to an OCI artifact.");
}
Expand Down
1 change: 0 additions & 1 deletion src/Bicep.Core.UnitTests/IServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
using Bicep.Core.Registry;
using Bicep.Core.Registry.Auth;
using Bicep.Core.Semantics.Namespaces;
using Bicep.Core.Syntax;
using Bicep.Core.TypeSystem;
using Bicep.Core.TypeSystem.Az;
using Bicep.Core.UnitTests.Configuration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public void ValidReferencesShouldParseCorrectly(ValidCase @case)
parsed.Tag.Should().Be(@case.ExpectedTag);
parsed.Digest.Should().Be(@case.ExpectedDigest);
parsed.ArtifactId.Should().Be(@case.Value);
parsed.UnqualifiedReference.Should().Be(@case.Value);
}
}

Expand Down Expand Up @@ -102,7 +103,7 @@ public void ValidReferenceShouldBeUriParseable(ValidCase @case)
[DataTestMethod]
public void InvalidReferencesShouldProduceExpectedError(string value, string expectedCode, string expectedError)
{
OciArtifactModuleReference.TryParse(null, value, BicepTestConstants.BuiltInConfigurationWithAllAnalyzersDisabled, RandomFileUri(), out var @ref, out var failureBuilder).Should().BeFalse();
OciModuleReference.TryParse(null, value, BicepTestConstants.BuiltInConfigurationWithAllAnalyzersDisabled, RandomFileUri(), out var @ref, out var failureBuilder).Should().BeFalse();
@ref.Should().BeNull();
failureBuilder!.Should().NotBeNull();

Expand Down Expand Up @@ -144,7 +145,7 @@ public void MismatchedReferencesShouldNotBeEqual(string package1, string package
[DataRow("foo bar ÄÄÄ")]
public void TryParse_InvalidAliasName_ReturnsFalseAndSetsErrorDiagnostic(string aliasName)
{
OciArtifactModuleReference.TryParse(aliasName, "", BicepTestConstants.BuiltInConfiguration, RandomFileUri(), out var reference, out var errorBuilder).Should().BeFalse();
OciModuleReference.TryParse(aliasName, "", BicepTestConstants.BuiltInConfiguration, RandomFileUri(), out var reference, out var errorBuilder).Should().BeFalse();

reference.Should().BeNull();
errorBuilder!.Should().HaveCode("BCP211");
Expand All @@ -158,7 +159,7 @@ public void TryParse_AliasNotInConfiguration_ReturnsFalseAndSetsErrorDiagnostic(
{
var configuration = BicepTestConstants.CreateMockConfiguration(configurationPath: configurationPath);

OciArtifactModuleReference.TryParse(aliasName, referenceValue, configuration, RandomFileUri(), out var reference, out var errorBuilder).Should().BeFalse();
OciModuleReference.TryParse(aliasName, referenceValue, configuration, RandomFileUri(), out var reference, out var errorBuilder).Should().BeFalse();

reference.Should().BeNull();
errorBuilder!.Should().NotBeNull();
Expand All @@ -170,7 +171,7 @@ public void TryParse_AliasNotInConfiguration_ReturnsFalseAndSetsErrorDiagnostic(
[DynamicData(nameof(GetInvalidAliasData), DynamicDataSourceType.Method)]
public void TryParse_InvalidAlias_ReturnsFalseAndSetsErrorDiagnostic(string aliasName, string referenceValue, RootConfiguration configuration, string expectedCode, string expectedMessage)
{
OciArtifactModuleReference.TryParse(aliasName, referenceValue, configuration, RandomFileUri(), out var reference, out var errorBuilder).Should().BeFalse();
OciModuleReference.TryParse(aliasName, referenceValue, configuration, RandomFileUri(), out var reference, out var errorBuilder).Should().BeFalse();

reference.Should().BeNull();
errorBuilder!.Should().NotBeNull();
Expand All @@ -182,22 +183,22 @@ public void TryParse_InvalidAlias_ReturnsFalseAndSetsErrorDiagnostic(string alia
[DynamicData(nameof(GetValidAliasData), DynamicDataSourceType.Method)]
public void TryGetModuleReference_ValidAlias_ReplacesReferenceValue(string aliasName, string referenceValue, string fullyQualifiedReferenceValue, RootConfiguration configuration)
{
OciArtifactModuleReference.TryParse(aliasName, referenceValue, configuration, RandomFileUri(), out var reference, out var errorBuilder).Should().BeTrue();
OciModuleReference.TryParse(aliasName, referenceValue, configuration, RandomFileUri(), out var reference, out var errorBuilder).Should().BeTrue();

reference.Should().NotBeNull();
reference!.FullyQualifiedReference.Should().Be(fullyQualifiedReferenceValue);
}


private static OciArtifactModuleReference Parse(string package)
private static OciModuleReference Parse(string package)
{
OciArtifactModuleReference.TryParse(null, package, BicepTestConstants.BuiltInConfigurationWithAllAnalyzersDisabled, RandomFileUri(), out var parsed, out var failureBuilder).Should().BeTrue();
OciModuleReference.TryParse(null, package, BicepTestConstants.BuiltInConfigurationWithAllAnalyzersDisabled, RandomFileUri(), out var parsed, out var failureBuilder).Should().BeTrue();
failureBuilder!.Should().BeNull();
parsed.Should().NotBeNull();
return parsed!;
}

private static (OciArtifactModuleReference, OciArtifactModuleReference) ParsePair(string first, string second) => (Parse(first), Parse(second));
private static (OciModuleReference, OciModuleReference) ParsePair(string first, string second) => (Parse(first), Parse(second));

private static IEnumerable<object[]> GetValidCases()
{
Expand Down
Loading