Skip to content

Commit

Permalink
Fixed dependency generation with existing resources (#7433)
Browse files Browse the repository at this point in the history
* workaround for File.Exists deadlock on win11

* fix
  • Loading branch information
majastrz authored Jul 1, 2022
1 parent 04263c4 commit 78a65ae
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 3 deletions.
64 changes: 64 additions & 0 deletions src/Bicep.Core.IntegrationTests/ScenarioTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3684,5 +3684,69 @@ public void Test_Issue2017()

result.Diagnostics.Should().OnlyContain(x => x.Styling == DiagnosticStyling.ShowCodeDeprecated);
}

/// <summary>
/// https://github.com/Azure/bicep/issues/6477
/// </summary>
[TestMethod]
public void Test_Issue6477()
{
var result = CompilationHelper.Compile(@"
param storageAccountName string
@allowed([
'Standard_GRS'
'Standard_ZRS'
])
@description('Storage account SKU. Standard_ZRS should be used if region supports, else Standard_GRS.')
param storageAccountSku string
resource storageAccountName_resource 'Microsoft.Storage/storageAccounts@2021-04-01' = {
name: storageAccountName
#disable-next-line no-loc-expr-outside-params
location: resourceGroup().location
sku: {
name: storageAccountSku
#disable-next-line BCP073
tier: 'Standard'
}
kind: 'StorageV2'
properties: {
allowBlobPublicAccess: true // Ibiza requires anonymous access to the container
minimumTlsVersion: 'TLS1_2'
supportsHttpsTrafficOnly: true
encryption: {
services: {
file: {
enabled: true
}
blob: {
enabled: true
}
}
keySource: 'Microsoft.Storage'
}
accessTier: 'Hot'
}
resource blobs 'blobServices' existing = {
name: 'default'
resource containers 'containers' = {
name: 'extension'
properties: {
publicAccess: 'Container'
}
}
}
}
");
result.ExcludingLinterDiagnostics().Should().NotHaveAnyDiagnostics();
result.Template.Should().HaveValueAtPath("$.resources[0].type", "Microsoft.Storage/storageAccounts/blobServices/containers");
result.Template.Should().HaveValueAtPath("$.resources[0].dependsOn", new JArray("[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]"));

result.Template.Should().HaveValueAtPath("$.resources[1].type", "Microsoft.Storage/storageAccounts");
result.Template.Should().NotHaveValueAtPath("$.resources[1].dependsOn");
}
}
}
19 changes: 17 additions & 2 deletions src/Bicep.Core/Emit/ResourceDependencyVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,21 @@ private ResourceDependencyVisitor(SemanticModel model, Options? options)

public override void VisitResourceDeclarationSyntax(ResourceDeclarationSyntax syntax)
{
static int GetIndexOfLastNonExistingAncestor(ImmutableArray<ResourceAncestorGraph.ResourceAncestor> ancestors)
{
for (int i = ancestors.Length - 1; i >= 0; i--)
{
if (!ancestors[i].Resource.IsExistingResource)
{
// we found the non-existing resource - we're done
return i;
}
}

// no non-existing resources are found in the ancestors list
return -1;
}

if (model.ResourceMetadata.TryLookup(syntax) is not DeclaredResourceMetadata resource)
{
// When invoked by BicepDeploymentGraphHandler, it's possible that the declaration is unbound.
Expand All @@ -73,13 +88,13 @@ public override void VisitResourceDeclarationSyntax(ResourceDeclarationSyntax sy

// Resource ancestors are always dependencies.
var ancestors = this.model.ResourceAncestors.GetAncestors(resource);
var lastAncestorIndex = ancestors.Length - 1;
var lastNonExistingAncestorIndex = GetIndexOfLastNonExistingAncestor(ancestors);

// save previous declaration as we may call this recursively
var prevDeclaration = this.currentDeclaration;

this.currentDeclaration = resource.Symbol;
this.resourceDependencies[resource.Symbol] = new HashSet<ResourceDependency>(ancestors.Select((a, i) => new ResourceDependency(a.Resource.Symbol, a.IndexExpression, i == lastAncestorIndex ? ResourceDependencyKind.Primary : ResourceDependencyKind.Transitive)));
this.resourceDependencies[resource.Symbol] = new HashSet<ResourceDependency>(ancestors.Select((a, i) => new ResourceDependency(a.Resource.Symbol, a.IndexExpression, i == lastNonExistingAncestorIndex ? ResourceDependencyKind.Primary : ResourceDependencyKind.Transitive)));
base.VisitResourceDeclarationSyntax(syntax);

// restore previous declaration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public ServerRequestHelper(TestContext testContext, MultiFileLanguageServerHelpe

public async Task<FileRequestHelper> OpenFile(string text)
=> await OpenFile(
new Uri($"file://{Guid.NewGuid():D}/{testContext.TestName}/main.bicep"),
new Uri($"file:///{Guid.NewGuid():D}/{testContext.TestName}/main.bicep"),
text);

public async Task<FileRequestHelper> OpenFile(Uri fileUri, string text)
Expand Down

0 comments on commit 78a65ae

Please sign in to comment.