From 5bac559c838fa8e9d793a70d49ca56fc57695d07 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 3 Mar 2026 19:17:20 +0000 Subject: [PATCH 1/6] Initial plan From 4e9aae5c5d669cd5c840bf28251a3017a50dca63 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 3 Mar 2026 19:29:11 +0000 Subject: [PATCH 2/6] Add dab autoentities-simulate CLI command Co-authored-by: RubenCerna2079 <32799214+RubenCerna2079@users.noreply.github.com> --- src/Cli.Tests/AutoSimulateTests.cs | 127 +++++++++++++++++ src/Cli/Commands/AutoSimulateOptions.cs | 49 +++++++ src/Cli/ConfigGenerator.cs | 173 ++++++++++++++++++++++++ src/Cli/Program.cs | 3 +- 4 files changed, 351 insertions(+), 1 deletion(-) create mode 100644 src/Cli.Tests/AutoSimulateTests.cs create mode 100644 src/Cli/Commands/AutoSimulateOptions.cs diff --git a/src/Cli.Tests/AutoSimulateTests.cs b/src/Cli.Tests/AutoSimulateTests.cs new file mode 100644 index 0000000000..1151bb4164 --- /dev/null +++ b/src/Cli.Tests/AutoSimulateTests.cs @@ -0,0 +1,127 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace Cli.Tests; + +/// +/// Tests for the autoentities-simulate CLI command. +/// +[TestClass] +public class AutoSimulateTests +{ + private IFileSystem? _fileSystem; + private FileSystemRuntimeConfigLoader? _runtimeConfigLoader; + + [TestInitialize] + public void TestInitialize() + { + _fileSystem = FileSystemUtils.ProvisionMockFileSystem(); + _runtimeConfigLoader = new FileSystemRuntimeConfigLoader(_fileSystem); + + ILoggerFactory loggerFactory = TestLoggerSupport.ProvisionLoggerFactory(); + ConfigGenerator.SetLoggerForCliConfigGenerator(loggerFactory.CreateLogger()); + SetCliUtilsLogger(loggerFactory.CreateLogger()); + } + + [TestCleanup] + public void TestCleanup() + { + _fileSystem = null; + _runtimeConfigLoader = null; + } + + /// + /// Tests that the simulate command fails when no config file is present. + /// + [TestMethod] + public void TestSimulateAutoentities_NoConfigFile() + { + // Arrange + AutoSimulateOptions options = new(); + + // Act + bool success = TrySimulateAutoentities(options, _runtimeConfigLoader!, _fileSystem!); + + // Assert + Assert.IsFalse(success); + } + + /// + /// Tests that the simulate command fails when the database type is not MSSQL. + /// + [TestMethod] + public void TestSimulateAutoentities_NonMssqlDatabase() + { + // Arrange: create a PostgreSQL config + InitOptions initOptions = new( + databaseType: DatabaseType.PostgreSQL, + connectionString: "testconnectionstring", + cosmosNoSqlDatabase: null, + cosmosNoSqlContainer: null, + graphQLSchemaPath: null, + setSessionContext: false, + hostMode: HostMode.Development, + corsOrigin: new List(), + authenticationProvider: EasyAuthType.AppService.ToString(), + restRequestBodyStrict: CliBool.True, + config: TEST_RUNTIME_CONFIG_FILE); + Assert.IsTrue(TryGenerateConfig(initOptions, _runtimeConfigLoader!, _fileSystem!)); + + AutoSimulateOptions options = new(config: TEST_RUNTIME_CONFIG_FILE); + + // Act + bool success = TrySimulateAutoentities(options, _runtimeConfigLoader!, _fileSystem!); + + // Assert + Assert.IsFalse(success); + } + + /// + /// Tests that the simulate command fails when no autoentities are defined in the config. + /// + [TestMethod] + public void TestSimulateAutoentities_NoAutoentitiesDefined() + { + // Arrange: create an MSSQL config without autoentities + InitOptions initOptions = CreateBasicInitOptionsForMsSqlWithConfig(config: TEST_RUNTIME_CONFIG_FILE); + Assert.IsTrue(TryGenerateConfig(initOptions, _runtimeConfigLoader!, _fileSystem!)); + + AutoSimulateOptions options = new(config: TEST_RUNTIME_CONFIG_FILE); + + // Act + bool success = TrySimulateAutoentities(options, _runtimeConfigLoader!, _fileSystem!); + + // Assert + Assert.IsFalse(success); + } + + /// + /// Tests that the simulate command options parse the output path correctly. + /// + [TestMethod] + public void TestSimulateAutoentitiesOptions_OutputPathParsed() + { + // Arrange + string outputPath = "simulation-output.csv"; + + // Act + AutoSimulateOptions options = new(output: outputPath, config: TEST_RUNTIME_CONFIG_FILE); + + // Assert + Assert.AreEqual(outputPath, options.Output); + Assert.AreEqual(TEST_RUNTIME_CONFIG_FILE, options.Config); + } + + /// + /// Tests that the simulate command options default output to null (console output). + /// + [TestMethod] + public void TestSimulateAutoentitiesOptions_DefaultOutputIsNull() + { + // Arrange & Act + AutoSimulateOptions options = new(); + + // Assert + Assert.IsNull(options.Output); + } +} diff --git a/src/Cli/Commands/AutoSimulateOptions.cs b/src/Cli/Commands/AutoSimulateOptions.cs new file mode 100644 index 0000000000..9486deb8e2 --- /dev/null +++ b/src/Cli/Commands/AutoSimulateOptions.cs @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System.IO.Abstractions; +using Azure.DataApiBuilder.Config; +using Azure.DataApiBuilder.Product; +using Cli.Constants; +using CommandLine; +using Microsoft.Extensions.Logging; +using static Cli.Utils; +using ILogger = Microsoft.Extensions.Logging.ILogger; + +namespace Cli.Commands +{ + /// + /// AutoSimulateOptions command options. + /// This command simulates the autoentities generation by querying the database + /// and displaying which entities would be created for each filter definition. + /// + [Verb("autoentities-simulate", isDefault: false, HelpText = "Simulate autoentities generation by querying the database and displaying the results.", Hidden = false)] + public class AutoSimulateOptions : Options + { + public AutoSimulateOptions( + string? output = null, + string? config = null) + : base(config) + { + Output = output; + } + + [Option('o', "output", Required = false, HelpText = "Path to output CSV file. If not specified, results are printed to the console.")] + public string? Output { get; } + + public int Handler(ILogger logger, FileSystemRuntimeConfigLoader loader, IFileSystem fileSystem) + { + logger.LogInformation("{productName} {version}", PRODUCT_NAME, ProductInfo.GetProductVersion()); + bool isSuccess = ConfigGenerator.TrySimulateAutoentities(this, loader, fileSystem); + if (isSuccess) + { + return CliReturnCode.SUCCESS; + } + else + { + logger.LogError("Failed to simulate autoentities."); + return CliReturnCode.GENERAL_ERROR; + } + } + } +} diff --git a/src/Cli/ConfigGenerator.cs b/src/Cli/ConfigGenerator.cs index 6d1fcf946d..95fe57c520 100644 --- a/src/Cli/ConfigGenerator.cs +++ b/src/Cli/ConfigGenerator.cs @@ -4,14 +4,17 @@ using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; using System.IO.Abstractions; +using System.Text; using Azure.DataApiBuilder.Config; using Azure.DataApiBuilder.Config.Converters; using Azure.DataApiBuilder.Config.NamingPolicies; using Azure.DataApiBuilder.Config.ObjectModel; using Azure.DataApiBuilder.Core; using Azure.DataApiBuilder.Core.Configurations; +using Azure.DataApiBuilder.Core.Resolvers; using Azure.DataApiBuilder.Service; using Cli.Commands; +using Microsoft.Data.SqlClient; using Microsoft.Extensions.Logging; using Serilog; using static Cli.Utils; @@ -3130,6 +3133,176 @@ private static AutoentityPatterns BuildAutoentityPatterns(AutoConfigOptions opti return parsedPermissions; } + /// + /// Simulates the autoentities generation by querying the database and displaying + /// which entities would be created for each autoentities filter definition. + /// When an output file path is provided, results are written as CSV; otherwise they are printed to the console. + /// + /// The simulate options provided by the user. + /// The config loader to read the existing config. + /// The filesystem used for reading the config file and writing output. + /// True if the simulation completed successfully; otherwise, false. + public static bool TrySimulateAutoentities(AutoSimulateOptions options, FileSystemRuntimeConfigLoader loader, IFileSystem fileSystem) + { + if (!TryGetConfigFileBasedOnCliPrecedence(loader, options.Config, out string runtimeConfigFile)) + { + return false; + } + + // Load config with env var replacement so the connection string is fully resolved. + DeserializationVariableReplacementSettings replacementSettings = new(doReplaceEnvVar: true); + if (!loader.TryLoadConfig(runtimeConfigFile, out RuntimeConfig? runtimeConfig, replacementSettings: replacementSettings)) + { + _logger.LogError("Failed to read the config file: {runtimeConfigFile}.", runtimeConfigFile); + return false; + } + + if (runtimeConfig.DataSource.DatabaseType != DatabaseType.MSSQL) + { + _logger.LogError("Autoentities simulation is only supported for MSSQL databases. Current database type: {DatabaseType}.", runtimeConfig.DataSource.DatabaseType); + return false; + } + + if (runtimeConfig.Autoentities?.Autoentities is null || runtimeConfig.Autoentities.Autoentities.Count == 0) + { + _logger.LogError("No autoentities definitions found in the config file."); + return false; + } + + string connectionString = runtimeConfig.DataSource.ConnectionString; + if (string.IsNullOrWhiteSpace(connectionString)) + { + _logger.LogError("Connection string is missing or empty."); + return false; + } + + MsSqlQueryBuilder queryBuilder = new(); + string query = queryBuilder.BuildGetAutoentitiesQuery(); + + Dictionary> results = new(); + + try + { + using SqlConnection connection = new(connectionString); + connection.Open(); + + foreach ((string filterName, Autoentity autoentity) in runtimeConfig.Autoentities.Autoentities) + { + string include = string.Join(",", autoentity.Patterns.Include); + string exclude = string.Join(",", autoentity.Patterns.Exclude); + string namePattern = autoentity.Patterns.Name; + + List<(string, string, string)> filterResults = new(); + + using SqlCommand command = new(query, connection); + command.Parameters.AddWithValue("@include_pattern", include); + command.Parameters.AddWithValue("@exclude_pattern", exclude); + command.Parameters.AddWithValue("@name_pattern", namePattern); + + using SqlDataReader reader = command.ExecuteReader(); + while (reader.Read()) + { + string entityName = reader["entity_name"]?.ToString() ?? string.Empty; + string objectName = reader["object"]?.ToString() ?? string.Empty; + string schemaName = reader["schema"]?.ToString() ?? string.Empty; + + if (!string.IsNullOrWhiteSpace(entityName) && !string.IsNullOrWhiteSpace(objectName)) + { + filterResults.Add((entityName, schemaName, objectName)); + } + } + + results[filterName] = filterResults; + } + } + catch (Exception ex) + { + _logger.LogError("Failed to query the database: {Message}", ex.Message); + return false; + } + + if (!string.IsNullOrWhiteSpace(options.Output)) + { + return WriteSimulationResultsToCsvFile(options.Output, results, fileSystem); + } + else + { + WriteSimulationResultsToConsole(results); + return true; + } + } + + /// + /// Writes the autoentities simulation results to the console in a human-readable format. + /// Results are grouped by filter name with entity-to-database-object mappings. + /// + /// The simulation results keyed by filter (definition) name. + private static void WriteSimulationResultsToConsole(Dictionary> results) + { + Console.WriteLine("AutoEntities Simulation Results"); + Console.WriteLine(); + + foreach ((string filterName, List<(string EntityName, string SchemaName, string ObjectName)> matches) in results) + { + Console.WriteLine($"Filter: {filterName}"); + Console.WriteLine($"Matches: {matches.Count}"); + Console.WriteLine(); + + if (matches.Count == 0) + { + Console.WriteLine("(no matches)"); + } + else + { + int maxEntityNameLength = matches.Max(m => m.EntityName.Length); + foreach ((string entityName, string schemaName, string objectName) in matches) + { + Console.WriteLine($"{entityName.PadRight(maxEntityNameLength)} -> {schemaName}.{objectName}"); + } + } + + Console.WriteLine(); + } + } + + /// + /// Writes the autoentities simulation results to a CSV file. + /// The file includes a header row followed by one row per matched entity. + /// If the file already exists it is overwritten. + /// + /// The file path to write the CSV output to. + /// The simulation results keyed by filter (definition) name. + /// The filesystem abstraction used for writing the file. + /// True if the file was written successfully; otherwise, false. + private static bool WriteSimulationResultsToCsvFile( + string outputPath, + Dictionary> results, + IFileSystem fileSystem) + { + try + { + StringBuilder sb = new(); + sb.AppendLine("filter_name,entity_name,database_object"); + + foreach ((string filterName, List<(string EntityName, string SchemaName, string ObjectName)> matches) in results) + { + foreach ((string entityName, string schemaName, string objectName) in matches) + { + sb.AppendLine($"{filterName},{entityName},{schemaName}.{objectName}"); + } + } + + fileSystem.File.WriteAllText(outputPath, sb.ToString()); + _logger.LogInformation("Simulation results written to {outputPath}.", outputPath); + return true; + } + catch (Exception ex) + { + _logger.LogError("Failed to write output file: {Message}", ex.Message); + return false; + } + } + /// /// Attempts to update the Azure Key Vault configuration options based on the provided values. /// Validates that any user-provided parameter value is valid and updates the runtime configuration accordingly. diff --git a/src/Cli/Program.cs b/src/Cli/Program.cs index e4732da095..d2becdc402 100644 --- a/src/Cli/Program.cs +++ b/src/Cli/Program.cs @@ -58,7 +58,7 @@ public static int Execute(string[] args, ILogger cliLogger, IFileSystem fileSyst }); // Parsing user arguments and executing required methods. - int result = parser.ParseArguments(args) + int result = parser.ParseArguments(args) .MapResult( (InitOptions options) => options.Handler(cliLogger, loader, fileSystem), (AddOptions options) => options.Handler(cliLogger, loader, fileSystem), @@ -68,6 +68,7 @@ public static int Execute(string[] args, ILogger cliLogger, IFileSystem fileSyst (AddTelemetryOptions options) => options.Handler(cliLogger, loader, fileSystem), (ConfigureOptions options) => options.Handler(cliLogger, loader, fileSystem), (AutoConfigOptions options) => options.Handler(cliLogger, loader, fileSystem), + (AutoSimulateOptions options) => options.Handler(cliLogger, loader, fileSystem), (ExportOptions options) => options.Handler(cliLogger, loader, fileSystem), errors => DabCliParserErrorHandler.ProcessErrorsAndReturnExitCode(errors)); From b5c113016797195a2bb58243e8e356e54d222047 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 3 Mar 2026 19:36:35 +0000 Subject: [PATCH 3/6] Address code review: add CSV quoting, column name constants, improve doc comment Co-authored-by: RubenCerna2079 <32799214+RubenCerna2079@users.noreply.github.com> --- src/Cli/Commands/AutoSimulateOptions.cs | 6 ++--- src/Cli/ConfigGenerator.cs | 30 +++++++++++++++++++++---- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/Cli/Commands/AutoSimulateOptions.cs b/src/Cli/Commands/AutoSimulateOptions.cs index 9486deb8e2..43dcefa0cf 100644 --- a/src/Cli/Commands/AutoSimulateOptions.cs +++ b/src/Cli/Commands/AutoSimulateOptions.cs @@ -13,9 +13,9 @@ namespace Cli.Commands { /// - /// AutoSimulateOptions command options. - /// This command simulates the autoentities generation by querying the database - /// and displaying which entities would be created for each filter definition. + /// Command options for the autoentities-simulate verb. + /// Simulates autoentities generation by querying the database and displaying + /// which entities would be created for each filter definition. /// [Verb("autoentities-simulate", isDefault: false, HelpText = "Simulate autoentities generation by querying the database and displaying the results.", Hidden = false)] public class AutoSimulateOptions : Options diff --git a/src/Cli/ConfigGenerator.cs b/src/Cli/ConfigGenerator.cs index 95fe57c520..4d65259546 100644 --- a/src/Cli/ConfigGenerator.cs +++ b/src/Cli/ConfigGenerator.cs @@ -3133,6 +3133,11 @@ private static AutoentityPatterns BuildAutoentityPatterns(AutoConfigOptions opti return parsedPermissions; } + // Column names returned by the autoentities SQL query. + private const string AUTOENTITIES_COLUMN_ENTITY_NAME = "entity_name"; + private const string AUTOENTITIES_COLUMN_OBJECT = "object"; + private const string AUTOENTITIES_COLUMN_SCHEMA = "schema"; + /// /// Simulates the autoentities generation by querying the database and displaying /// which entities would be created for each autoentities filter definition. @@ -3202,9 +3207,9 @@ public static bool TrySimulateAutoentities(AutoSimulateOptions options, FileSyst using SqlDataReader reader = command.ExecuteReader(); while (reader.Read()) { - string entityName = reader["entity_name"]?.ToString() ?? string.Empty; - string objectName = reader["object"]?.ToString() ?? string.Empty; - string schemaName = reader["schema"]?.ToString() ?? string.Empty; + string entityName = reader[AUTOENTITIES_COLUMN_ENTITY_NAME]?.ToString() ?? string.Empty; + string objectName = reader[AUTOENTITIES_COLUMN_OBJECT]?.ToString() ?? string.Empty; + string schemaName = reader[AUTOENTITIES_COLUMN_SCHEMA]?.ToString() ?? string.Empty; if (!string.IsNullOrWhiteSpace(entityName) && !string.IsNullOrWhiteSpace(objectName)) { @@ -3288,7 +3293,7 @@ private static bool WriteSimulationResultsToCsvFile( { foreach ((string entityName, string schemaName, string objectName) in matches) { - sb.AppendLine($"{filterName},{entityName},{schemaName}.{objectName}"); + sb.AppendLine($"{QuoteCsvValue(filterName)},{QuoteCsvValue(entityName)},{QuoteCsvValue($"{schemaName}.{objectName}")}"); } } @@ -3303,6 +3308,23 @@ private static bool WriteSimulationResultsToCsvFile( } } + /// + /// Quotes a value for inclusion in a CSV field. + /// If the value contains a comma, double-quote, or newline, it is wrapped in double-quotes + /// and any embedded double-quotes are escaped by doubling them. + /// + /// The value to quote. + /// A properly escaped CSV field value. + private static string QuoteCsvValue(string value) + { + if (value.Contains(',') || value.Contains('"') || value.Contains('\n') || value.Contains('\r')) + { + return $"\"{value.Replace("\"", "\"\"")}\""; + } + + return value; + } + /// /// Attempts to update the Azure Key Vault configuration options based on the provided values. /// Validates that any user-provided parameter value is valid and updates the runtime configuration accordingly. From ac61097bbf9334edae8c33e85421a33fa16b9c4e Mon Sep 17 00:00:00 2001 From: Ruben Cerna Date: Wed, 4 Mar 2026 16:22:07 -0800 Subject: [PATCH 4/6] Change name for command --- src/Cli.Tests/AutoSimulateTests.cs | 12 ++++++------ ...mulateOptions.cs => AutoConfigSimulateOptions.cs} | 8 ++++---- src/Cli/Program.cs | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) rename src/Cli/Commands/{AutoSimulateOptions.cs => AutoConfigSimulateOptions.cs} (82%) diff --git a/src/Cli.Tests/AutoSimulateTests.cs b/src/Cli.Tests/AutoSimulateTests.cs index 1151bb4164..5405042330 100644 --- a/src/Cli.Tests/AutoSimulateTests.cs +++ b/src/Cli.Tests/AutoSimulateTests.cs @@ -4,7 +4,7 @@ namespace Cli.Tests; /// -/// Tests for the autoentities-simulate CLI command. +/// Tests for the auto-config-simulate CLI command. /// [TestClass] public class AutoSimulateTests @@ -37,7 +37,7 @@ public void TestCleanup() public void TestSimulateAutoentities_NoConfigFile() { // Arrange - AutoSimulateOptions options = new(); + AutoConfigSimulateOptions options = new(); // Act bool success = TrySimulateAutoentities(options, _runtimeConfigLoader!, _fileSystem!); @@ -67,7 +67,7 @@ public void TestSimulateAutoentities_NonMssqlDatabase() config: TEST_RUNTIME_CONFIG_FILE); Assert.IsTrue(TryGenerateConfig(initOptions, _runtimeConfigLoader!, _fileSystem!)); - AutoSimulateOptions options = new(config: TEST_RUNTIME_CONFIG_FILE); + AutoConfigSimulateOptions options = new(config: TEST_RUNTIME_CONFIG_FILE); // Act bool success = TrySimulateAutoentities(options, _runtimeConfigLoader!, _fileSystem!); @@ -86,7 +86,7 @@ public void TestSimulateAutoentities_NoAutoentitiesDefined() InitOptions initOptions = CreateBasicInitOptionsForMsSqlWithConfig(config: TEST_RUNTIME_CONFIG_FILE); Assert.IsTrue(TryGenerateConfig(initOptions, _runtimeConfigLoader!, _fileSystem!)); - AutoSimulateOptions options = new(config: TEST_RUNTIME_CONFIG_FILE); + AutoConfigSimulateOptions options = new(config: TEST_RUNTIME_CONFIG_FILE); // Act bool success = TrySimulateAutoentities(options, _runtimeConfigLoader!, _fileSystem!); @@ -105,7 +105,7 @@ public void TestSimulateAutoentitiesOptions_OutputPathParsed() string outputPath = "simulation-output.csv"; // Act - AutoSimulateOptions options = new(output: outputPath, config: TEST_RUNTIME_CONFIG_FILE); + AutoConfigSimulateOptions options = new(output: outputPath, config: TEST_RUNTIME_CONFIG_FILE); // Assert Assert.AreEqual(outputPath, options.Output); @@ -119,7 +119,7 @@ public void TestSimulateAutoentitiesOptions_OutputPathParsed() public void TestSimulateAutoentitiesOptions_DefaultOutputIsNull() { // Arrange & Act - AutoSimulateOptions options = new(); + AutoConfigSimulateOptions options = new(); // Assert Assert.IsNull(options.Output); diff --git a/src/Cli/Commands/AutoSimulateOptions.cs b/src/Cli/Commands/AutoConfigSimulateOptions.cs similarity index 82% rename from src/Cli/Commands/AutoSimulateOptions.cs rename to src/Cli/Commands/AutoConfigSimulateOptions.cs index 43dcefa0cf..205c8d7d9e 100644 --- a/src/Cli/Commands/AutoSimulateOptions.cs +++ b/src/Cli/Commands/AutoConfigSimulateOptions.cs @@ -13,14 +13,14 @@ namespace Cli.Commands { /// - /// Command options for the autoentities-simulate verb. + /// Command options for the auto-config-simulate verb. /// Simulates autoentities generation by querying the database and displaying /// which entities would be created for each filter definition. /// - [Verb("autoentities-simulate", isDefault: false, HelpText = "Simulate autoentities generation by querying the database and displaying the results.", Hidden = false)] - public class AutoSimulateOptions : Options + [Verb("auto-config-simulate", isDefault: false, HelpText = "Simulate autoentities generation by querying the database and displaying the results.", Hidden = false)] + public class AutoConfigSimulateOptions : Options { - public AutoSimulateOptions( + public AutoConfigSimulateOptions( string? output = null, string? config = null) : base(config) diff --git a/src/Cli/Program.cs b/src/Cli/Program.cs index d2becdc402..de16ed27f5 100644 --- a/src/Cli/Program.cs +++ b/src/Cli/Program.cs @@ -58,7 +58,7 @@ public static int Execute(string[] args, ILogger cliLogger, IFileSystem fileSyst }); // Parsing user arguments and executing required methods. - int result = parser.ParseArguments(args) + int result = parser.ParseArguments(args) .MapResult( (InitOptions options) => options.Handler(cliLogger, loader, fileSystem), (AddOptions options) => options.Handler(cliLogger, loader, fileSystem), @@ -68,7 +68,7 @@ public static int Execute(string[] args, ILogger cliLogger, IFileSystem fileSyst (AddTelemetryOptions options) => options.Handler(cliLogger, loader, fileSystem), (ConfigureOptions options) => options.Handler(cliLogger, loader, fileSystem), (AutoConfigOptions options) => options.Handler(cliLogger, loader, fileSystem), - (AutoSimulateOptions options) => options.Handler(cliLogger, loader, fileSystem), + (AutoConfigSimulateOptions options) => options.Handler(cliLogger, loader, fileSystem), (ExportOptions options) => options.Handler(cliLogger, loader, fileSystem), errors => DabCliParserErrorHandler.ProcessErrorsAndReturnExitCode(errors)); From b66791745def52d72c6372be965356807b9fdc86 Mon Sep 17 00:00:00 2001 From: Ruben Cerna Date: Thu, 5 Mar 2026 14:34:39 -0800 Subject: [PATCH 5/6] Fix class name --- src/Cli/ConfigGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/ConfigGenerator.cs b/src/Cli/ConfigGenerator.cs index 4d65259546..36236c119b 100644 --- a/src/Cli/ConfigGenerator.cs +++ b/src/Cli/ConfigGenerator.cs @@ -3147,7 +3147,7 @@ private static AutoentityPatterns BuildAutoentityPatterns(AutoConfigOptions opti /// The config loader to read the existing config. /// The filesystem used for reading the config file and writing output. /// True if the simulation completed successfully; otherwise, false. - public static bool TrySimulateAutoentities(AutoSimulateOptions options, FileSystemRuntimeConfigLoader loader, IFileSystem fileSystem) + public static bool TrySimulateAutoentities(AutoConfigSimulateOptions options, FileSystemRuntimeConfigLoader loader, IFileSystem fileSystem) { if (!TryGetConfigFileBasedOnCliPrecedence(loader, options.Config, out string runtimeConfigFile)) { From 2966009e49190f780c1fa8b4d97283668d5a70d4 Mon Sep 17 00:00:00 2001 From: Ruben Cerna Date: Fri, 6 Mar 2026 16:34:37 -0800 Subject: [PATCH 6/6] Get rid of unecessary testing --- src/Cli.Tests/AutoSimulateTests.cs | 46 ------------------------------ src/Cli/ConfigGenerator.cs | 2 +- 2 files changed, 1 insertion(+), 47 deletions(-) diff --git a/src/Cli.Tests/AutoSimulateTests.cs b/src/Cli.Tests/AutoSimulateTests.cs index 5405042330..14f4412f7c 100644 --- a/src/Cli.Tests/AutoSimulateTests.cs +++ b/src/Cli.Tests/AutoSimulateTests.cs @@ -30,52 +30,6 @@ public void TestCleanup() _runtimeConfigLoader = null; } - /// - /// Tests that the simulate command fails when no config file is present. - /// - [TestMethod] - public void TestSimulateAutoentities_NoConfigFile() - { - // Arrange - AutoConfigSimulateOptions options = new(); - - // Act - bool success = TrySimulateAutoentities(options, _runtimeConfigLoader!, _fileSystem!); - - // Assert - Assert.IsFalse(success); - } - - /// - /// Tests that the simulate command fails when the database type is not MSSQL. - /// - [TestMethod] - public void TestSimulateAutoentities_NonMssqlDatabase() - { - // Arrange: create a PostgreSQL config - InitOptions initOptions = new( - databaseType: DatabaseType.PostgreSQL, - connectionString: "testconnectionstring", - cosmosNoSqlDatabase: null, - cosmosNoSqlContainer: null, - graphQLSchemaPath: null, - setSessionContext: false, - hostMode: HostMode.Development, - corsOrigin: new List(), - authenticationProvider: EasyAuthType.AppService.ToString(), - restRequestBodyStrict: CliBool.True, - config: TEST_RUNTIME_CONFIG_FILE); - Assert.IsTrue(TryGenerateConfig(initOptions, _runtimeConfigLoader!, _fileSystem!)); - - AutoConfigSimulateOptions options = new(config: TEST_RUNTIME_CONFIG_FILE); - - // Act - bool success = TrySimulateAutoentities(options, _runtimeConfigLoader!, _fileSystem!); - - // Assert - Assert.IsFalse(success); - } - /// /// Tests that the simulate command fails when no autoentities are defined in the config. /// diff --git a/src/Cli/ConfigGenerator.cs b/src/Cli/ConfigGenerator.cs index 36236c119b..31c7e91e9f 100644 --- a/src/Cli/ConfigGenerator.cs +++ b/src/Cli/ConfigGenerator.cs @@ -3177,7 +3177,7 @@ public static bool TrySimulateAutoentities(AutoConfigSimulateOptions options, Fi string connectionString = runtimeConfig.DataSource.ConnectionString; if (string.IsNullOrWhiteSpace(connectionString)) { - _logger.LogError("Connection string is missing or empty."); + _logger.LogError("Connection string is missing or empty in config file."); return false; }