src/Bicep.LangServer.IntegrationTests/DeployBicepFileActionTest.cs (355 lines of code) (raw):
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using Azure.Core;
using Azure.ResourceManager;
using Bicep.Core.UnitTests;
using Bicep.Core.UnitTests.FileSystem;
using Bicep.Core.UnitTests.Mock;
using Bicep.Core.UnitTests.Utils;
using Bicep.LanguageServer;
using Bicep.LanguageServer.Deploy;
using Bicep.LanguageServer.Handlers;
using Bicep.LanguageServer.Providers;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.WindowsAzure.ResourceStack.Common.Json;
using Moq;
using Newtonsoft.Json.Linq;
using OmniSharp.Extensions.LanguageServer.Protocol;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
using OmniSharp.Extensions.LanguageServer.Protocol.Workspace;
namespace Bicep.LangServer.IntegrationTests
{
public class MockArmClientProvider : IArmClientProvider
{
public ArmClient createArmClient(TokenCredential credential, string? defaultSubscriptionId, ArmClientOptions options)
{
var clientMock = StrictMock.Of<ArmClient>();
return clientMock.Object;
}
}
[TestClass]
public class DeployBicepFileActionTest
{
[NotNull]
public TestContext? TestContext { get; set; }
[TestMethod]
public async Task IncorrectUpdateOption_WithBicepparamFile_ReturnsError()
{
var bicepFileUri = InMemoryFileResolver.GetFileUri("/path/to/main.bicep");
var bicepparamFileUri = InMemoryFileResolver.GetFileUri("/path/to/param.bicepparam");
var fileTextsByUri = new Dictionary<DocumentUri, string>()
{
[bicepFileUri] = "",
[bicepparamFileUri] = ""
};
using var helper = await LanguageServerHelper.StartServerWithText(
TestContext,
fileTextsByUri,
bicepFileUri,
services => services
.WithArmClientProvider(new MockArmClientProvider()));
var client = helper.Client;
var bicepDeploymentStartParams = new BicepDeploymentStartParams(
bicepFileUri.AbsolutePath,
bicepparamFileUri.AbsolutePath,
string.Empty,
string.Empty,
string.Empty,
string.Empty,
"fake-token-123",
"123456",
string.Empty,
string.Empty,
string.Empty,
true,
string.Empty,
LanguageServer.Deploy.ParametersFileUpdateOption.Create,
new List<BicepUpdatedDeploymentParameter>(),
"https://management.azure.com/",
"https://management.core.windows.net/");
var deploymentStartResponse = await client.Workspace.ExecuteCommandWithResponse<BicepDeploymentStartResponse>(
new Command
{
Name = "deploy/start",
Arguments = new JArray(
bicepDeploymentStartParams.ToJToken()
)
}
);
deploymentStartResponse.isSuccess.Should().BeFalse();
deploymentStartResponse.outputMessage.Should().Be("Cannot create/overwrite/update parameter files when using a bicep parameters file");
deploymentStartResponse.viewDeploymentInPortalMessage.Should().BeNull();
}
[TestMethod]
public async Task ProvidingUpdateParameterValues_WithBicepparamFile_ReturnsError()
{
var bicepFileUri = InMemoryFileResolver.GetFileUri("/path/to/main.bicep");
var bicepparamFileUri = InMemoryFileResolver.GetFileUri("/path/to/param.bicepparam");
var fileTextsByUri = new Dictionary<DocumentUri, string>()
{
[bicepFileUri] = "",
[bicepparamFileUri] = ""
};
using var helper = await LanguageServerHelper.StartServerWithText(
TestContext,
fileTextsByUri,
bicepFileUri,
services => services
.WithArmClientProvider(new MockArmClientProvider()));
var client = helper.Client;
var bicepDeploymentStartParams = new BicepDeploymentStartParams(
bicepFileUri.AbsolutePath,
bicepparamFileUri.AbsolutePath,
string.Empty,
string.Empty,
string.Empty,
string.Empty,
"fake-token-123",
"123456",
string.Empty,
string.Empty,
string.Empty,
true,
string.Empty,
LanguageServer.Deploy.ParametersFileUpdateOption.None,
new List<BicepUpdatedDeploymentParameter>{
new("foo", "bar", false, null)
},
"https://management.azure.com/",
"https://management.core.windows.net/");
var deploymentStartResponse = await client.Workspace.ExecuteCommandWithResponse<BicepDeploymentStartResponse>(
new Command
{
Name = "deploy/start",
Arguments = new JArray(
bicepDeploymentStartParams.ToJToken()
)
}
);
deploymentStartResponse.isSuccess.Should().BeFalse();
deploymentStartResponse.outputMessage.Should().Be("Cannot update parameters for bicep parameter file");
}
[TestMethod]
public async Task NotProvidingParameterFileName_WithJsonParameterFile_ReturnsError()
{
var bicepFileUri = InMemoryFileResolver.GetFileUri("/path/to/main.bicep");
var paramFileUri = InMemoryFileResolver.GetFileUri("/path/to/param.json");
var fileTextsByUri = new Dictionary<DocumentUri, string>()
{
[bicepFileUri] = "",
[paramFileUri] = ""
};
using var helper = await LanguageServerHelper.StartServerWithText(
TestContext,
fileTextsByUri,
bicepFileUri,
services => services
.WithArmClientProvider(new MockArmClientProvider()));
var client = helper.Client;
var bicepDeploymentStartParams = new BicepDeploymentStartParams(
bicepFileUri.AbsolutePath,
paramFileUri.AbsolutePath,
string.Empty,
string.Empty,
string.Empty,
string.Empty,
"fake-token-123",
"123456",
string.Empty,
string.Empty,
string.Empty,
true,
null, //ParametersFileName
LanguageServer.Deploy.ParametersFileUpdateOption.None,
new List<BicepUpdatedDeploymentParameter>(),
"https://management.azure.com/",
"https://management.core.windows.net/");
var deploymentStartResponse = await client.Workspace.ExecuteCommandWithResponse<BicepDeploymentStartResponse>(
new Command
{
Name = "deploy/start",
Arguments = new JArray(
bicepDeploymentStartParams.ToJToken()
)
}
);
deploymentStartResponse.isSuccess.Should().BeFalse();
deploymentStartResponse.outputMessage.Should().Be("ParametersFileName must be provided with JSON parameters file");
}
[TestMethod]
public async Task StartDeploymentAsync_WithInvalidParameterFilePath_ReturnsDeploymentFailedMessage()
{
var bicepFileUri = InMemoryFileResolver.GetFileUri("/path/to/main.bicep");
var invalidParamFilePath = @"c:\parameter.json";
var fileTextsByUri = new Dictionary<DocumentUri, string>()
{
[bicepFileUri] = "",
};
using var helper = await LanguageServerHelper.StartServerWithText(
TestContext,
fileTextsByUri,
bicepFileUri,
services => services
.WithArmClientProvider(new MockArmClientProvider()));
var client = helper.Client;
var bicepDeploymentStartParams = new BicepDeploymentStartParams(
bicepFileUri.AbsolutePath,
invalidParamFilePath,
string.Empty,
string.Empty,
string.Empty,
string.Empty,
"fake-token-123",
"123456",
string.Empty,
string.Empty,
string.Empty,
true,
string.Empty,
LanguageServer.Deploy.ParametersFileUpdateOption.None,
new List<BicepUpdatedDeploymentParameter>(),
"https://management.azure.com/",
"https://management.core.windows.net/");
var deploymentStartResponse = await client.Workspace.ExecuteCommandWithResponse<BicepDeploymentStartResponse>(
new Command
{
Name = "deploy/start",
Arguments = new JArray(
bicepDeploymentStartParams.ToJToken()
)
}
);
var expectedDeploymentOutputMessage = string.Format(LangServerResources.InvalidParameterFileDeploymentFailedMessage, bicepFileUri.AbsolutePath, invalidParamFilePath, @"Could not find file");
deploymentStartResponse.isSuccess.Should().BeFalse();
deploymentStartResponse.outputMessage.Should().Contain(expectedDeploymentOutputMessage);
deploymentStartResponse.viewDeploymentInPortalMessage.Should().BeNull();
}
[TestMethod]
public async Task StartDeploymentAsync_WithInvalidParameterFileContents_ReturnsDeploymentFailedMessage()
{
var bicepFileUri = InMemoryFileResolver.GetFileUri("/path/to/main.bicep");
var parametersFilePath = FileHelper.SaveResultFile(TestContext, "parameters.json", "invalid_parameters_file");
var fileTextsByUri = new Dictionary<DocumentUri, string>()
{
[bicepFileUri] = "",
};
using var helper = await LanguageServerHelper.StartServerWithText(
TestContext,
fileTextsByUri,
bicepFileUri,
services => services
.WithArmClientProvider(new MockArmClientProvider()));
var client = helper.Client;
var bicepDeploymentStartParams = new BicepDeploymentStartParams(
bicepFileUri.AbsolutePath,
parametersFilePath,
string.Empty,
string.Empty,
string.Empty,
string.Empty,
"fake-token-123",
"123456",
string.Empty,
string.Empty,
string.Empty,
true,
string.Empty,
LanguageServer.Deploy.ParametersFileUpdateOption.None,
new List<BicepUpdatedDeploymentParameter>(),
"https://management.azure.com/",
"https://management.core.windows.net/");
var deploymentStartResponse = await client.Workspace.ExecuteCommandWithResponse<BicepDeploymentStartResponse>(
new Command
{
Name = "deploy/start",
Arguments = new JArray(
bicepDeploymentStartParams.ToJToken()
)
}
);
var expectedDeploymentOutputMessage = string.Format(LangServerResources.InvalidParameterFileDeploymentFailedMessage, bicepFileUri.AbsolutePath, parametersFilePath, @"Unexpected character encountered while parsing value: i. Path '', line 0, position 0.");
deploymentStartResponse.isSuccess.Should().BeFalse();
deploymentStartResponse.outputMessage.Should().Contain(expectedDeploymentOutputMessage);
deploymentStartResponse.viewDeploymentInPortalMessage.Should().BeNull();
}
//Issue #10985
[TestMethod]
public async Task StartDeploymentAsync_WithNoParameterFile_Succeeds()
{
var bicepFileUri = InMemoryFileResolver.GetFileUri("/path/to/main.bicep");
var parametersFilePath = FileHelper.SaveResultFile(TestContext, "parameters.json", "invalid_parameters_file");
var fileTextsByUri = new Dictionary<DocumentUri, string>()
{
[bicepFileUri] = "",
};
var deploymentHelperMock = StrictMock.Of<IDeploymentHelper>();
deploymentHelperMock.Setup(deploymentHelper => deploymentHelper.StartDeploymentAsync(
It.IsAny<IDeploymentCollectionProvider>(),
It.IsAny<ArmClient>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<JsonElement>(),
It.IsAny<IDeploymentOperationsCache>()
).Result).Returns(new BicepDeploymentStartResponse(true, "", null)); ;
using var helper = await LanguageServerHelper.StartServerWithText(
TestContext,
fileTextsByUri,
bicepFileUri,
services => services
.WithArmClientProvider(new MockArmClientProvider())
.WithDeploymentHelper(deploymentHelperMock.Object));
var client = helper.Client;
var bicepDeploymentStartParams = new BicepDeploymentStartParams(
bicepFileUri.AbsolutePath,
null, //null value here means a deployment without a parameters file
string.Empty,
string.Empty,
string.Empty,
string.Empty,
"fake-token-123",
"123456",
string.Empty,
string.Empty,
string.Empty,
true,
string.Empty,
LanguageServer.Deploy.ParametersFileUpdateOption.None,
new List<BicepUpdatedDeploymentParameter>(),
"https://management.azure.com/",
"https://management.core.windows.net/");
var deploymentStartResponse = await client.Workspace.ExecuteCommandWithResponse<BicepDeploymentStartResponse>(
new Command
{
Name = "deploy/start",
Arguments = new JArray(
bicepDeploymentStartParams.ToJToken()
)
}
);
deploymentHelperMock.Verify(deploymentHelper => deploymentHelper.StartDeploymentAsync(
It.IsAny<IDeploymentCollectionProvider>(),
It.IsAny<ArmClient>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<string>(),
It.IsAny<JsonElement>(),
It.IsAny<IDeploymentOperationsCache>()
), Times.Once);
deploymentStartResponse.isSuccess.Should().BeTrue();
deploymentStartResponse.outputMessage.Should().Be("");
deploymentStartResponse.viewDeploymentInPortalMessage.Should().BeNull();
}
}
}