Skip to content
3 changes: 0 additions & 3 deletions src/Cli.Tests/AddEntityTests.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using Azure.DataApiBuilder.Config.ObjectModel;
using Cli.Commands;

namespace Cli.Tests
{
/// <summary>
Expand Down
136 changes: 136 additions & 0 deletions src/Cli.Tests/ConfigGeneratorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

namespace Cli.Tests;

/// <summary>
/// Config Generation Tests for CLI.
/// </summary>
[TestClass]
public class ConfigGeneratorTests
{
private IFileSystem? _fileSystem;
private RuntimeConfigLoader? _runtimeConfigLoader;

[TestInitialize]
public void TestInitialize()
{
_fileSystem = FileSystemUtils.ProvisionMockFileSystem();

_runtimeConfigLoader = new RuntimeConfigLoader(_fileSystem);

ILoggerFactory loggerFactory = TestLoggerSupport.ProvisionLoggerFactory();

SetLoggerForCliConfigGenerator(loggerFactory.CreateLogger<ConfigGenerator>());
SetCliUtilsLogger(loggerFactory.CreateLogger<Utils>());
}

[TestCleanup]
public void TestCleanup()
{
_fileSystem = null;
_runtimeConfigLoader = null;
}

/// <summary>
/// Tests that user provided config file is successfully generated when that file is not already present.
/// </summary>
[DataTestMethod]
[DataRow(true, false, DisplayName = "Failed to generate config file when user provided config file is present.")]
[DataRow(false, true, DisplayName = "Successfully generated config file when user provided config file is not present.")]
public void TryGenerateConfig_WithUserProvidedConfig(
bool isConfigFilePresent,
bool isConfigGenerationSuccessful)
{
HandleConfigFileCreationAndDeletion(TEST_RUNTIME_CONFIG_FILE, isConfigFilePresent);
Assert.AreEqual(isConfigFilePresent, _fileSystem!.File.Exists(TEST_RUNTIME_CONFIG_FILE));

InitOptions options = CreateBasicInitOptionsForMsSqlWithConfig(config: TEST_RUNTIME_CONFIG_FILE);

// Mocking logger to assert on logs
Mock<ILogger<ConfigGenerator>> loggerMock = new();
ConfigGenerator.SetLoggerForCliConfigGenerator(loggerMock.Object);

Assert.AreEqual(isConfigGenerationSuccessful, ConfigGenerator.TryGenerateConfig(options, _runtimeConfigLoader!, _fileSystem!));

if (!isConfigFilePresent)
{
Assert.AreEqual(isConfigGenerationSuccessful, _fileSystem!.File.Exists(TEST_RUNTIME_CONFIG_FILE));
}
else
{
// Assert on the log message to verify the failure
loggerMock.Verify(
x => x.Log(
LogLevel.Error,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((o, t) => o.ToString()!.Contains($"{TEST_RUNTIME_CONFIG_FILE} already exists.")),
It.IsAny<Exception?>(),
(Func<It.IsAnyType, Exception?, string>)It.IsAny<object>()
),
Times.Once
);
}
}

/// <summary>
/// Tests that environment config file is successfully generated when that file is not already present.
/// When environment variable is not set, it should generate the default config file.
/// </summary>
[DataTestMethod]
[DataRow(true, false, "Test", "dab-config.Test.json", DisplayName = "Failed to generate the config file when environment config file is present.")]
[DataRow(false, true, "Test", "dab-config.Test.json", DisplayName = "Successfully generated the config file when environment config file is not present.")]
[DataRow(false, true, "", "dab-config.json", DisplayName = "Successfully generated the config file when environment config file is not present and environment variable is set as empty.")]
[DataRow(false, true, null, "dab-config.json", DisplayName = "Successfully generated the config file when environment config file is not present and environment variable is not set.")]
public void TryGenerateConfig_UsingEnvironmentVariable(
bool isConfigFilePresent,
bool isConfigGenerationSuccessful,
string? environmentValue,
string configFileName)
{
Environment.SetEnvironmentVariable(RUNTIME_ENVIRONMENT_VAR_NAME, environmentValue);
HandleConfigFileCreationAndDeletion(configFileName, isConfigFilePresent);
Assert.AreEqual(isConfigFilePresent, _fileSystem!.File.Exists(configFileName));

InitOptions options = CreateBasicInitOptionsForMsSqlWithConfig();

// Mocking logger to assert on logs
Mock<ILogger<ConfigGenerator>> loggerMock = new();
ConfigGenerator.SetLoggerForCliConfigGenerator(loggerMock.Object);

Assert.AreEqual(isConfigGenerationSuccessful, ConfigGenerator.TryGenerateConfig(options, _runtimeConfigLoader!, _fileSystem!));
if (!isConfigFilePresent)
{
Assert.AreEqual(isConfigGenerationSuccessful, _fileSystem!.File.Exists(configFileName));
}
else
{
// Assert on the log message to verify the failure
loggerMock.Verify(
x => x.Log(
LogLevel.Error,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((o, t) => o.ToString()!.Contains($"{configFileName} already exists.")),
It.IsAny<Exception?>(),
(Func<It.IsAnyType, Exception?, string>)It.IsAny<object>()
),
Times.Once
);
}
}

/// <summary>
/// This method handles the creation and deletion of a configuration file.
/// </summary>
private void HandleConfigFileCreationAndDeletion(string configFilePath, bool configFilePresent)
{
if (!configFilePresent)
{
_fileSystem!.File.Delete(configFilePath);
}
else if (configFilePresent)
{
_fileSystem!.File.Create(configFilePath).Dispose();
}
}
}
3 changes: 0 additions & 3 deletions src/Cli.Tests/EndToEndTests.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.IO.Abstractions;
using System.IO.Abstractions.TestingHelpers;
using Azure.DataApiBuilder.Config.ObjectModel;
using Azure.DataApiBuilder.Service;

namespace Cli.Tests;
Expand Down
1 change: 0 additions & 1 deletion src/Cli.Tests/EnvironmentTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Text.Json;
using Azure.DataApiBuilder.Config.Converters;

namespace Cli.Tests;
Expand Down
1 change: 0 additions & 1 deletion src/Cli.Tests/FileSystemUtils.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.IO.Abstractions.TestingHelpers;
using System.Reflection;

namespace Cli.Tests;
Expand Down
5 changes: 0 additions & 5 deletions src/Cli.Tests/InitTests.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.IO.Abstractions;
using System.IO.Abstractions.TestingHelpers;
using Azure.DataApiBuilder.Config.ObjectModel;
using Cli.Commands;

namespace Cli.Tests
{
/// <summary>
Expand Down
1 change: 0 additions & 1 deletion src/Cli.Tests/ModuleInitializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Licensed under the MIT License.

using System.Runtime.CompilerServices;
using Azure.DataApiBuilder.Config.ObjectModel;

namespace Cli.Tests;

Expand Down
20 changes: 20 additions & 0 deletions src/Cli.Tests/TestHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1095,5 +1095,25 @@ public static Process ExecuteDabCommand(string command, string flags)
}
}
}";

/// <summary>
/// Creates basic initialization options for MS SQL config.
/// </summary>
/// <param name="config">Optional config file name.</param>
/// <returns>InitOptions</returns>
public static InitOptions CreateBasicInitOptionsForMsSqlWithConfig(string? config = null)
{
return new(
databaseType: DatabaseType.MSSQL,
connectionString: "testconnectionstring",
cosmosNoSqlDatabase: null,
cosmosNoSqlContainer: null,
graphQLSchemaPath: null,
setSessionContext: true,
hostMode: HostMode.Development,
corsOrigin: new List<string>(),
authenticationProvider: EasyAuthType.StaticWebApps.ToString(),
config: config);
}
}
}
2 changes: 0 additions & 2 deletions src/Cli.Tests/UpdateEntityTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// Licensed under the MIT License.

using Azure.DataApiBuilder.Config.Converters;
using Azure.DataApiBuilder.Config.ObjectModel;
using Cli.Commands;

namespace Cli.Tests
{
Expand Down
6 changes: 6 additions & 0 deletions src/Cli.Tests/Usings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@
// Licensed under the MIT License.

global using System.Diagnostics;
global using System.IO.Abstractions;
global using System.IO.Abstractions.TestingHelpers;
global using System.Text.Json;
global using Azure.DataApiBuilder.Config;
global using Azure.DataApiBuilder.Config.ObjectModel;
global using Azure.DataApiBuilder.Service.Exceptions;
global using Cli.Commands;
global using Microsoft.Extensions.Logging;
global using Microsoft.VisualStudio.TestTools.UnitTesting;
global using Moq;
global using Newtonsoft.Json.Linq;
global using static Azure.DataApiBuilder.Config.RuntimeConfigLoader;
global using static Cli.ConfigGenerator;
global using static Cli.Tests.TestHelper;
global using static Cli.Utils;
3 changes: 0 additions & 3 deletions src/Cli.Tests/UtilsTests.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.IO.Abstractions.TestingHelpers;
using Azure.DataApiBuilder.Config.ObjectModel;

namespace Cli.Tests;

[TestClass]
Expand Down
25 changes: 20 additions & 5 deletions src/Cli/ConfigGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,38 @@ public static void SetLoggerForCliConfigGenerator(
/// </summary>
public static bool TryGenerateConfig(InitOptions options, RuntimeConfigLoader loader, IFileSystem fileSystem)
{
if (!TryGetConfigFileBasedOnCliPrecedence(loader, options.Config, out string runtimeConfigFile))
string runtimeConfigFile = RuntimeConfigLoader.DEFAULT_CONFIG_FILE_NAME;
if (!string.IsNullOrWhiteSpace(options.Config))
{
runtimeConfigFile = RuntimeConfigLoader.DEFAULT_CONFIG_FILE_NAME;
_logger.LogInformation($"Creating a new config file: {runtimeConfigFile}");
_logger.LogInformation("Generating user provided config file with name: {configFileName}", options.Config);
runtimeConfigFile = options.Config;
}
else
{
string? environmentValue = Environment.GetEnvironmentVariable(RuntimeConfigLoader.RUNTIME_ENVIRONMENT_VAR_NAME);
if (!string.IsNullOrWhiteSpace(environmentValue))
{
_logger.LogInformation("The environment variable {variableName} has a value of {variableValue}", RuntimeConfigLoader.RUNTIME_ENVIRONMENT_VAR_NAME, environmentValue);
runtimeConfigFile = RuntimeConfigLoader.GetEnvironmentFileName(RuntimeConfigLoader.CONFIGFILE_NAME, environmentValue);
_logger.LogInformation("Generating environment config file: {configPath}", fileSystem.Path.GetFullPath(runtimeConfigFile));
}
else
{
_logger.LogInformation("Generating default config file: {config}", fileSystem.Path.GetFullPath(runtimeConfigFile));
}
}

// File existence checked to avoid overwriting the existing configuration.
if (fileSystem.File.Exists(runtimeConfigFile))
{
_logger.LogError("Config file: {runtimeConfigFile} already exists. Please provide a different name or remove the existing config file.", runtimeConfigFile);
_logger.LogError("Config file: {runtimeConfigFile} already exists. Please provide a different name or remove the existing config file.",
fileSystem.Path.GetFullPath(runtimeConfigFile));
return false;
}

// Creating a new json file with runtime configuration
if (!TryCreateRuntimeConfig(options, loader, fileSystem, out RuntimeConfig? runtimeConfig))
{
_logger.LogError($"Failed to create the runtime config file.");
return false;
}

Expand Down
9 changes: 9 additions & 0 deletions src/Config/RuntimeConfigLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,15 @@ private static string GetOverriddenName(string fileName)
return $"{fileName}.overrides{CONFIG_EXTENSION}";
}

/// <summary>
/// Generates the name of the file based on environment value.
/// NOTE: Input File name should not contain extension
/// </summary>
public static string GetEnvironmentFileName(string fileName, string environmentValue)
{
return $"{fileName}.{environmentValue}{CONFIG_EXTENSION}";
}

public bool DoesFileExistInCurrentDirectory(string fileName)
{
string currentDir = _fileSystem.Directory.GetCurrentDirectory();
Expand Down