From d2ea04f3462fbb962ffc5f8e0b431883bd0f64e9 Mon Sep 17 00:00:00 2001 From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com> Date: Mon, 1 Jun 2026 10:56:25 -0300 Subject: [PATCH 01/10] Fix stress tests running in Help mode; replace failOnTestFailure with warnOnTestFailure - Move STRESS_CONFIG_FILE from dotnet run -e arg to task env: property to fix DotNetCoreCLI@2 leaking the env var value as an app argument, which hit the default switch case and set RunMode.Help. - Rename failOnTestFailure to warnOnTestFailure (default false) with inverted semantics: false = failures fail the run, true = warnings only. All test steps always execute regardless of this setting. --- eng/pipelines/stress/stress-tests-job.yml | 26 ++++++++++++------- .../stress/stress-tests-pipeline.yml | 10 +++---- eng/pipelines/stress/stress-tests-stage.yml | 12 +++++---- 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/eng/pipelines/stress/stress-tests-job.yml b/eng/pipelines/stress/stress-tests-job.yml index a216c23864..362b1f9550 100644 --- a/eng/pipelines/stress/stress-tests-job.yml +++ b/eng/pipelines/stress/stress-tests-job.yml @@ -48,10 +48,11 @@ parameters: - name: jobNameSuffix type: string - # True to fail the job when stress tests fail. When false, test failures produce warnings - # (SucceededWithIssues) but do not fail the job. - - name: failOnTestFailure + # When true, test failures produce warnings (SucceededWithIssues) but do not fail the job. + # When false, test failures fail the job. All test steps always run regardless of this setting. + - name: warnOnTestFailure type: boolean + default: false # The list of .NET Framework runtimes to test against. - name: netFrameworkTestRuntimes @@ -116,6 +117,7 @@ jobs: value: >- --verbosity ${{ parameters.dotnetVerbosity }} --configuration ${{ parameters.buildConfiguration }} + --no-build # The contents of the config file to use for all tests. We will write this to a JSON file and # then point to it via the STRESS_CONFIG_FILE environment variable. @@ -194,29 +196,33 @@ jobs: # - eq(variables['buildSucceeded'], 'true') gates on the flag set above, so tests are # skipped entirely if the build or any setup step failed (since there's nothing to run). # - # continueOnError: ${{ not(parameters.failOnTestFailure) }} - # - When failOnTestFailure is false, continueOnError is true: a test failure marks the + # continueOnError: ${{ parameters.warnOnTestFailure }} + # - When warnOnTestFailure is true, continueOnError is true: a test failure marks the # step and job as SucceededWithIssues (orange warning) rather than Failed. - # - When failOnTestFailure is true, continueOnError is false: a test failure fails the + # - When warnOnTestFailure is false, continueOnError is false: a test failure fails the # job (red), though subsequent runtimes still run due to the condition above. # - ${{ each runtime in parameters.netTestRuntimes }}: - task: DotNetCoreCLI@2 displayName: Test [${{ runtime }}] condition: and(succeededOrFailed(), eq(variables['buildSucceeded'], 'true')) - continueOnError: ${{ not(parameters.failOnTestFailure) }} + continueOnError: ${{ parameters.warnOnTestFailure }} + env: + STRESS_CONFIG_FILE: config.json inputs: command: run projects: $(project) - arguments: $(runArguments) --no-build -f ${{ runtime }} -e STRESS_CONFIG_FILE=config.json -- $(testArguments) + arguments: $(runArguments) -f ${{ runtime }} -- $(testArguments) # Run the stress tests for each .NET Framework runtime. - ${{ each runtime in parameters.netFrameworkTestRuntimes }}: - task: DotNetCoreCLI@2 displayName: Test [${{ runtime }}] condition: and(succeededOrFailed(), eq(variables['buildSucceeded'], 'true')) - continueOnError: ${{ not(parameters.failOnTestFailure) }} + continueOnError: ${{ parameters.warnOnTestFailure }} + env: + STRESS_CONFIG_FILE: config.json inputs: command: run projects: $(project) - arguments: $(runArguments) --no-build -f ${{ runtime }} -e STRESS_CONFIG_FILE=config.json -- $(testArguments) + arguments: $(runArguments) -f ${{ runtime }} -- $(testArguments) diff --git a/eng/pipelines/stress/stress-tests-pipeline.yml b/eng/pipelines/stress/stress-tests-pipeline.yml index 1f2e356461..e9c1f3ecb8 100644 --- a/eng/pipelines/stress/stress-tests-pipeline.yml +++ b/eng/pipelines/stress/stress-tests-pipeline.yml @@ -73,10 +73,10 @@ parameters: type: boolean default: false - # True to fail the pipeline when stress tests fail. When false (default), test failures produce - # warnings but do not fail the overall pipeline run. - - name: failOnTestFailure - displayName: Fail pipeline on test failure + # When true, test failures produce warnings (SucceededWithIssues) but do not fail the pipeline. + # When false (default), test failures fail the pipeline. + - name: warnOnTestFailure + displayName: Warn (not fail) on test failure type: boolean default: false @@ -105,5 +105,5 @@ stages: parameters: buildConfiguration: ${{ parameters.buildConfiguration }} debug: ${{ parameters.debug }} - failOnTestFailure: ${{ parameters.failOnTestFailure }} + warnOnTestFailure: ${{ parameters.warnOnTestFailure }} dotnetVerbosity: ${{ parameters.dotnetVerbosity }} diff --git a/eng/pipelines/stress/stress-tests-stage.yml b/eng/pipelines/stress/stress-tests-stage.yml index f641ea0e7e..bfe36ab31b 100644 --- a/eng/pipelines/stress/stress-tests-stage.yml +++ b/eng/pipelines/stress/stress-tests-stage.yml @@ -32,9 +32,11 @@ parameters: type: boolean default: false - # True to fail the job when stress tests fail. When false, test failures produce warnings. - - name: failOnTestFailure + # When true, test failures produce warnings (SucceededWithIssues) but do not fail the job. + # When false, test failures fail the job. All test steps always run regardless of this setting. + - name: warnOnTestFailure type: boolean + default: false # The verbosity level for the dotnet CLI commands. - name: dotnetVerbosity @@ -80,7 +82,7 @@ stages: debug: ${{ parameters.debug }} displayNamePrefix: Linux dotnetVerbosity: ${{ parameters.dotnetVerbosity }} - failOnTestFailure: ${{ parameters.failOnTestFailure }} + warnOnTestFailure: ${{ parameters.warnOnTestFailure }} jobNameSuffix: linux netTestRuntimes: ${{ parameters.netTestRuntimes }} poolName: ADO-CI-1ES-Pool @@ -100,7 +102,7 @@ stages: debug: ${{ parameters.debug }} displayNamePrefix: Win dotnetVerbosity: ${{ parameters.dotnetVerbosity }} - failOnTestFailure: ${{ parameters.failOnTestFailure }} + warnOnTestFailure: ${{ parameters.warnOnTestFailure }} jobNameSuffix: windows # Note that we include the .NET Framework runtimes for test runs on Windows. netFrameworkTestRuntimes: ${{ parameters.netFrameworkTestRuntimes }} @@ -124,7 +126,7 @@ stages: debug: ${{ parameters.debug }} displayNamePrefix: macOS dotnetVerbosity: ${{ parameters.dotnetVerbosity }} - failOnTestFailure: ${{ parameters.failOnTestFailure }} + warnOnTestFailure: ${{ parameters.warnOnTestFailure }} jobNameSuffix: macos netTestRuntimes: ${{ parameters.netTestRuntimes }} # We don't have any 1ES Hosted Pool images for macOS, so we use a generic one from Azure From 6827b81efd65950fca275e333d0cc74777707853 Mon Sep 17 00:00:00 2001 From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com> Date: Mon, 1 Jun 2026 11:19:58 -0300 Subject: [PATCH 02/10] Simplify stress runner: remove dead code paths, fix version detection - Remove RunMode enum, RunVerify, ExitWithError, and Help mode - Init() returns exit code directly; Main() short-circuits on non-zero - Rename RunStress() to Run() (only remaining path) - Fix GetMdsVersion() to use correct namespace (Microsoft.Data.SqlClient.ThisAssembly) - PrintHelp() dumps received args with quoting for diagnostics --- .../SqlClient.Stress.Runner/Program.cs | 82 +++++-------------- 1 file changed, 20 insertions(+), 62 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Program.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Program.cs index 6b49692aa7..2307f26494 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Program.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Program.cs @@ -16,25 +16,19 @@ class Program private static bool s_debugMode = false; static int Main(string[] args) { - Init(args); + int exitCode = Init(args); + if (exitCode != 0) + { + return exitCode; + } return Run(); } - public enum RunMode - { - RunAll, - RunVerify, - Help, - ExitWithError - }; - - private static RunMode s_mode = RunMode.RunAll; private static IEnumerable s_tests; private static StressEngine s_eng; - private static string s_error; private static bool s_console = false; - public static void Init(string[] args) + public static int Init(string[] args) { for (int i = 0; i < args.Length; i++) { @@ -45,10 +39,6 @@ public static void Init(string[] args) TestFinder.AssemblyName = new AssemblyName(assemblyName); break; - case "-all": - s_mode = RunMode.RunAll; - break; - case "-override": TestMetrics.Overrides.Add(args[++i], args[++i]); break; @@ -69,10 +59,6 @@ public static void Init(string[] args) TestMetrics.StressThreads = int.Parse(args[++i]); break; - case "-verify": - s_mode = RunMode.RunVerify; - break; - case "-console": s_console = true; break; @@ -118,8 +104,8 @@ public static void Init(string[] args) break; default: - s_mode = RunMode.Help; - break; + PrintHelp(args); + return 1; } } @@ -137,36 +123,22 @@ public static void Init(string[] args) } else { - Program.s_error = string.Format("Assembly {0} cannot be found.", TestFinder.AssemblyName); - s_mode = RunMode.ExitWithError; + Console.Error.WriteLine("Error: No assembly specified. Use -a ."); + PrintHelp(args); + return 1; } + + return 0; } - public static int Run() + private static void PrintHelp(string[] args) { - if (TestFinder.AssemblyName == null) + Console.WriteLine($"Arguments ({args.Length}):"); + for (int i = 0; i < args.Length; i++) { - s_mode = RunMode.Help; + Console.WriteLine($" [{i}] \"{args[i]}\""); } - switch (s_mode) - { - case RunMode.RunAll: - return RunStress(); - - case RunMode.RunVerify: - return RunVerify(); - - case RunMode.ExitWithError: - return ExitWithError(); - - case RunMode.Help: - default: - return PrintHelp(); - } - } - - private static int PrintHelp() - { + Console.WriteLine(); Console.WriteLine("stresstest.exe [-a ] "); Console.WriteLine(); Console.WriteLine(" -a should specify path to the assembly containing the tests."); @@ -204,8 +176,6 @@ private static int PrintHelp() Console.WriteLine(); Console.WriteLine(" -deadlockdetection True or False to enable deadlock detection. Default is false"); Console.WriteLine(); - - return 1; } private static void PrintConfigSummary() @@ -215,7 +185,6 @@ private static void PrintConfigSummary() Console.WriteLine(border); Console.WriteLine($"MDS Version: {GetMdsVersion()}"); Console.WriteLine($"Test Assembly Name: {TestFinder.AssemblyName}"); - Console.WriteLine($"Run mode: {Enum.GetName(typeof(RunMode), s_mode)}"); foreach (var item in TestMetrics.Overrides) { Console.WriteLine($"Override: {item.Key} = {item.Value}"); @@ -235,18 +204,7 @@ private static void PrintConfigSummary() Console.WriteLine(border); } - private static int ExitWithError() - { - Environment.FailFast("Exit with error(s)."); - return 1; - } - - private static int RunVerify() - { - throw new NotImplementedException(); - } - - private static int RunStress() + private static int Run() { if (!s_console) { @@ -275,7 +233,7 @@ private static string GetMdsVersion() // See: tools/targets/GenerateThisAssemblyCs.targets // var assembly = typeof(SqlConnection).Assembly; - var type = assembly.GetType("System.ThisAssembly"); + var type = assembly.GetType("Microsoft.Data.SqlClient.ThisAssembly"); if (type is null) { return ""; From 315f8786f059b1e7fe78f07853f83d1cff206e16 Mon Sep 17 00:00:00 2001 From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com> Date: Mon, 1 Jun 2026 11:36:59 -0300 Subject: [PATCH 03/10] Fix DotNetCoreCLI@2 run command mangling arguments The task's 'command: run' mode puts all 'arguments' content after '--' as application args, ignoring the user-specified '--' separator. This caused dotnet-run flags (--verbosity, --configuration, --no-build, -f) to be passed to the stress runner app instead of to dotnet-run itself. Switch to 'command: custom' + 'custom: run' which passes arguments literally, giving us full control over placement. --- eng/pipelines/stress/stress-tests-job.yml | 12 ++++++------ eng/pipelines/stress/stress-tests-stage.yml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/eng/pipelines/stress/stress-tests-job.yml b/eng/pipelines/stress/stress-tests-job.yml index 362b1f9550..b0f51746d9 100644 --- a/eng/pipelines/stress/stress-tests-job.yml +++ b/eng/pipelines/stress/stress-tests-job.yml @@ -210,9 +210,9 @@ jobs: env: STRESS_CONFIG_FILE: config.json inputs: - command: run - projects: $(project) - arguments: $(runArguments) -f ${{ runtime }} -- $(testArguments) + command: custom + custom: run + arguments: --project $(project) $(runArguments) -f ${{ runtime }} -- $(testArguments) # Run the stress tests for each .NET Framework runtime. - ${{ each runtime in parameters.netFrameworkTestRuntimes }}: @@ -223,6 +223,6 @@ jobs: env: STRESS_CONFIG_FILE: config.json inputs: - command: run - projects: $(project) - arguments: $(runArguments) -f ${{ runtime }} -- $(testArguments) + command: custom + custom: run + arguments: --project $(project) $(runArguments) -f ${{ runtime }} -- $(testArguments) diff --git a/eng/pipelines/stress/stress-tests-stage.yml b/eng/pipelines/stress/stress-tests-stage.yml index bfe36ab31b..67168c160e 100644 --- a/eng/pipelines/stress/stress-tests-stage.yml +++ b/eng/pipelines/stress/stress-tests-stage.yml @@ -58,7 +58,7 @@ parameters: # in the stress test Directory.Build.props and the TFMs that SqlClient ships. - name: netTestRuntimes type: object - default: [net8.0, net9.0] + default: [net8.0, net9.0, net10.0] stages: - stage: stress_tests_stage From 09a1d252030b537f043806542d15f524354abfb3 Mon Sep 17 00:00:00 2001 From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com> Date: Mon, 1 Jun 2026 12:40:04 -0300 Subject: [PATCH 04/10] Replace dotnet run with dotnet exec to bypass SDK argument parsing regression dotnet run in SDK 10.0.300 incorrectly forwards its own options (--verbosity, --configuration, --no-build) as application arguments on the CI agent (Ubuntu 22.04). This cannot be reproduced locally with the same SDK version but manifests consistently on hosted agents. Since we build separately anyway (--no-build), switch to dotnet exec which directly invokes the built DLL without any argument parsing ambiguity. --- eng/pipelines/stress/stress-tests-job.yml | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/eng/pipelines/stress/stress-tests-job.yml b/eng/pipelines/stress/stress-tests-job.yml index b0f51746d9..5f7b086d06 100644 --- a/eng/pipelines/stress/stress-tests-job.yml +++ b/eng/pipelines/stress/stress-tests-job.yml @@ -112,12 +112,9 @@ jobs: --verbosity ${{ parameters.dotnetVerbosity }} -p:Configuration=${{ parameters.buildConfiguration }} - # dotnet CLI arguments for run. - - name: runArguments - value: >- - --verbosity ${{ parameters.dotnetVerbosity }} - --configuration ${{ parameters.buildConfiguration }} - --no-build + # The output directory where the built stress test binaries are placed. + - name: outputDir + value: $(Build.SourcesDirectory)/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/bin/${{ parameters.buildConfiguration }} # The contents of the config file to use for all tests. We will write this to a JSON file and # then point to it via the STRESS_CONFIG_FILE environment variable. @@ -188,6 +185,11 @@ jobs: # Run the stress tests for each .NET runtime. # + # We use `dotnet exec` instead of `dotnet run` because SDK 10.0.300 has a regression where + # `dotnet run` forwards its own options (--verbosity, --configuration, --no-build) as + # application arguments on hosted Ubuntu agents. Since we build separately above, `dotnet + # exec` is both simpler and immune to argument-parsing changes in the SDK. + # # The condition and continueOnError work together to achieve the following behavior: # # condition: and(succeededOrFailed(), eq(variables['buildSucceeded'], 'true')) @@ -211,8 +213,8 @@ jobs: STRESS_CONFIG_FILE: config.json inputs: command: custom - custom: run - arguments: --project $(project) $(runArguments) -f ${{ runtime }} -- $(testArguments) + custom: exec + arguments: $(outputDir)/${{ runtime }}/stresstest.dll $(testArguments) # Run the stress tests for each .NET Framework runtime. - ${{ each runtime in parameters.netFrameworkTestRuntimes }}: @@ -224,5 +226,5 @@ jobs: STRESS_CONFIG_FILE: config.json inputs: command: custom - custom: run - arguments: --project $(project) $(runArguments) -f ${{ runtime }} -- $(testArguments) + custom: exec + arguments: $(outputDir)/${{ runtime }}/stresstest.dll $(testArguments) From 77fbbd60c5c256aab4eba449c02f4ce3f655392b Mon Sep 17 00:00:00 2001 From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com> Date: Mon, 1 Jun 2026 13:04:45 -0300 Subject: [PATCH 05/10] Address Copilot review feedback on PR #4329 - Remove stale -all and -verify options from PrintHelp (no run modes remain) - Clarify netTestRuntimes comment to note net10.0 is tested but not shipped - Use CmdLine@2 for .NET Framework test loop (dotnet exec cannot run net462 exe) --- eng/pipelines/stress/stress-tests-job.yml | 7 +++---- eng/pipelines/stress/stress-tests-stage.yml | 4 ++-- .../tests/StressTests/SqlClient.Stress.Runner/Program.cs | 4 ---- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/eng/pipelines/stress/stress-tests-job.yml b/eng/pipelines/stress/stress-tests-job.yml index 5f7b086d06..4fb061cc4b 100644 --- a/eng/pipelines/stress/stress-tests-job.yml +++ b/eng/pipelines/stress/stress-tests-job.yml @@ -217,14 +217,13 @@ jobs: arguments: $(outputDir)/${{ runtime }}/stresstest.dll $(testArguments) # Run the stress tests for each .NET Framework runtime. + # .NET Framework assemblies cannot be run via `dotnet exec`; invoke the exe directly. - ${{ each runtime in parameters.netFrameworkTestRuntimes }}: - - task: DotNetCoreCLI@2 + - task: CmdLine@2 displayName: Test [${{ runtime }}] condition: and(succeededOrFailed(), eq(variables['buildSucceeded'], 'true')) continueOnError: ${{ parameters.warnOnTestFailure }} env: STRESS_CONFIG_FILE: config.json inputs: - command: custom - custom: exec - arguments: $(outputDir)/${{ runtime }}/stresstest.dll $(testArguments) + script: '"$(outputDir)/${{ runtime }}/stresstest.exe" $(testArguments)' diff --git a/eng/pipelines/stress/stress-tests-stage.yml b/eng/pipelines/stress/stress-tests-stage.yml index 67168c160e..8738769a87 100644 --- a/eng/pipelines/stress/stress-tests-stage.yml +++ b/eng/pipelines/stress/stress-tests-stage.yml @@ -54,8 +54,8 @@ parameters: type: object default: [net462] - # The list of .NET runtimes to test against. These must align with the TargetFrameworks defined - # in the stress test Directory.Build.props and the TFMs that SqlClient ships. + # The list of .NET runtimes to test against. These should include the TFMs that SqlClient ships + # as well as any upcoming runtimes being validated (e.g. net10.0 is tested but not yet shipped). - name: netTestRuntimes type: object default: [net8.0, net9.0, net10.0] diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Program.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Program.cs index 2307f26494..ff76b4d15f 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Program.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Program.cs @@ -145,10 +145,6 @@ private static void PrintHelp(string[] args) Console.WriteLine(); Console.WriteLine("Supported options are:"); Console.WriteLine(); - Console.WriteLine(" -all Run all tests - best for debugging, not perf measurements."); - Console.WriteLine(); - Console.WriteLine(" -verify Run in functional verification mode."); - Console.WriteLine(); Console.WriteLine(" -duration Duration of the test in seconds."); Console.WriteLine(); Console.WriteLine(" -threads Number of threads to use."); From e9fdf2c8f9271e73d9478c12e118ad84a324102b Mon Sep 17 00:00:00 2001 From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com> Date: Tue, 2 Jun 2026 16:23:06 -0300 Subject: [PATCH 06/10] fix: rename pipeline variables to avoid dotnet CLI env var injection The dotnet CLI's System.CommandLine reads environment variables named {COMMAND}ARGUMENTS (e.g. RUNARGUMENTS, BUILDARGUMENTS, TESTARGUMENTS) and silently injects their content into parsed arguments. Since ADO exposes all pipeline variables as uppercased env vars, variables named 'runArguments', 'buildArguments', or 'testArguments' caused the stress runner to receive SDK options in its args[], triggering Help mode. Changes: - Rename buildArguments -> dotnetBuildOpts - Rename testArguments -> stressTestOpts - Add dotnetRunOpts variable for shared dotnet run options - Revert dotnet exec back to dotnet run (the real fix is the rename) - Use ${{ variables.* }} for compile-time expansion - Document the gotcha in ado-pipelines.instructions.md --- .../ado-pipelines.instructions.md | 14 +++++ eng/pipelines/stress/stress-tests-job.yml | 54 ++++++++++--------- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/.github/instructions/ado-pipelines.instructions.md b/.github/instructions/ado-pipelines.instructions.md index 9260a78b3d..7e0d02e4e2 100644 --- a/.github/instructions/ado-pipelines.instructions.md +++ b/.github/instructions/ado-pipelines.instructions.md @@ -110,6 +110,20 @@ Test timeout — `--blame-hang-timeout 10m` (configured in `build.proj` and thre - `localFeedPath` = `$(Build.SourcesDirectory)/packages` — local NuGet feed for inter-package deps - `packagePath` = `$(Build.SourcesDirectory)/output` — NuGet pack output +## Variable Naming — Avoid `{COMMAND}ARGUMENTS` Names + +The dotnet CLI (via System.CommandLine) reads environment variables named `{COMMAND}ARGUMENTS` and silently injects their content into the parsed arguments for that subcommand. Because Azure DevOps automatically exposes all pipeline variables as uppercased environment variables, a pipeline variable named `runArguments` becomes `RUNARGUMENTS`, which `dotnet run` reads and injects into the application's `args[]` — bypassing the `--` separator. + +**Forbidden variable names** (any casing): +- `runArguments` — injected into `dotnet run` +- `buildArguments` — injected into `dotnet build` +- `testArguments` — injected into `dotnet test` +- Any name matching `{dotnet-subcommand}Arguments` + +**Use instead**: `dotnetBuildOpts`, `dotnetRunOpts`, `stressTestArgs`, or other names that do not match the `{COMMAND}ARGUMENTS` pattern. + +This affects ALL .NET SDK versions (8.0+). The injection is invisible in `[command]` log lines, making it extremely hard to diagnose. The only symptom is the application receiving unexpected arguments. + ## Conventions When Editing Pipelines - Always use templates for reusable logic — do not inline complex steps diff --git a/eng/pipelines/stress/stress-tests-job.yml b/eng/pipelines/stress/stress-tests-job.yml index 4fb061cc4b..b0a2b90624 100644 --- a/eng/pipelines/stress/stress-tests-job.yml +++ b/eng/pipelines/stress/stress-tests-job.yml @@ -106,16 +106,6 @@ jobs: - name: project value: $(Build.SourcesDirectory)/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/SqlClient.Stress.Runner.csproj - # dotnet CLI arguments for build. - - name: buildArguments - value: >- - --verbosity ${{ parameters.dotnetVerbosity }} - -p:Configuration=${{ parameters.buildConfiguration }} - - # The output directory where the built stress test binaries are placed. - - name: outputDir - value: $(Build.SourcesDirectory)/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/bin/${{ parameters.buildConfiguration }} - # The contents of the config file to use for all tests. We will write this to a JSON file and # then point to it via the STRESS_CONFIG_FILE environment variable. - name: configContent @@ -136,8 +126,28 @@ jobs: } ] - # Stress test command-line arguments. - - name: testArguments + # IMPORTANT: Do NOT name pipeline variables "runArguments", "buildArguments", or + # "testArguments". ADO exposes all pipeline variables as environment variables (uppercased), + # and the dotnet CLI's System.CommandLine reads env vars matching {COMMAND}ARGUMENTS (e.g. + # RUNARGUMENTS, BUILDARGUMENTS) and silently injects their content into the parsed arguments — + # bypassing the "--" separator. This causes app arguments to contain SDK options and triggers + # unintended behavior. + + # dotnet CLI options for build. + - name: dotnetBuildOpts + value: >- + --verbosity ${{ parameters.dotnetVerbosity }} + -p:Configuration=${{ parameters.buildConfiguration }} + + # dotnet run options shared by all test steps (framework is appended per-step). + - name: dotnetRunOpts + value: >- + --no-build + --verbosity ${{ parameters.dotnetVerbosity }} + --configuration ${{ parameters.buildConfiguration }} + + # Stress test options passed after the "--" separator. + - name: stressTestOpts value: -a SqlClient.Stress.Tests -console steps: @@ -177,7 +187,7 @@ jobs: inputs: command: build projects: $(project) - arguments: $(buildArguments) + arguments: ${{ variables.dotnetBuildOpts }} # Set a flag so test steps can distinguish a build failure from a test failure. - pwsh: Write-Host "##vso[task.setvariable variable=buildSucceeded]true" @@ -185,11 +195,6 @@ jobs: # Run the stress tests for each .NET runtime. # - # We use `dotnet exec` instead of `dotnet run` because SDK 10.0.300 has a regression where - # `dotnet run` forwards its own options (--verbosity, --configuration, --no-build) as - # application arguments on hosted Ubuntu agents. Since we build separately above, `dotnet - # exec` is both simpler and immune to argument-parsing changes in the SDK. - # # The condition and continueOnError work together to achieve the following behavior: # # condition: and(succeededOrFailed(), eq(variables['buildSucceeded'], 'true')) @@ -212,18 +217,19 @@ jobs: env: STRESS_CONFIG_FILE: config.json inputs: - command: custom - custom: exec - arguments: $(outputDir)/${{ runtime }}/stresstest.dll $(testArguments) + command: run + projects: $(project) + arguments: ${{ variables.dotnetRunOpts }} -f ${{ runtime }} -- ${{ variables.stressTestOpts }} # Run the stress tests for each .NET Framework runtime. - # .NET Framework assemblies cannot be run via `dotnet exec`; invoke the exe directly. - ${{ each runtime in parameters.netFrameworkTestRuntimes }}: - - task: CmdLine@2 + - task: DotNetCoreCLI@2 displayName: Test [${{ runtime }}] condition: and(succeededOrFailed(), eq(variables['buildSucceeded'], 'true')) continueOnError: ${{ parameters.warnOnTestFailure }} env: STRESS_CONFIG_FILE: config.json inputs: - script: '"$(outputDir)/${{ runtime }}/stresstest.exe" $(testArguments)' + command: run + projects: $(project) + arguments: ${{ variables.dotnetRunOpts }} -f ${{ runtime }} -- ${{ variables.stressTestOpts }} From d2ce122dc7c4f08294cdbf9577b5fd31417196cc Mon Sep 17 00:00:00 2001 From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com> Date: Tue, 2 Jun 2026 17:38:00 -0300 Subject: [PATCH 07/10] Choosing pool name based on Azure DevOps project name. --- eng/pipelines/stress/stress-tests-stage.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/eng/pipelines/stress/stress-tests-stage.yml b/eng/pipelines/stress/stress-tests-stage.yml index 8738769a87..901a66f21a 100644 --- a/eng/pipelines/stress/stress-tests-stage.yml +++ b/eng/pipelines/stress/stress-tests-stage.yml @@ -71,6 +71,15 @@ stages: - name: saPassword value: $[stageDependencies.secrets_stage.secrets_job.outputs['SaPassword.Value']] + # The 1ES pool name, determined automatically by ADO project: + # - ADO.Net -> ADO-1ES-Pool + # - public -> ADO-CI-1ES-Pool + - name: poolName + ${{ if eq(variables['System.TeamProject'], 'ADO.Net') }}: + value: ADO-1ES-Pool + ${{ else }}: + value: ADO-CI-1ES-Pool + jobs: # ---------------------------------------------------------------------------------------------- @@ -85,7 +94,7 @@ stages: warnOnTestFailure: ${{ parameters.warnOnTestFailure }} jobNameSuffix: linux netTestRuntimes: ${{ parameters.netTestRuntimes }} - poolName: ADO-CI-1ES-Pool + poolName: ${{ variables.poolName }} saPassword: $(saPassword) sqlSetupStep: template: /eng/pipelines/common/templates/steps/configure-sql-server-linux-step.yml@self @@ -107,7 +116,7 @@ stages: # Note that we include the .NET Framework runtimes for test runs on Windows. netFrameworkTestRuntimes: ${{ parameters.netFrameworkTestRuntimes }} netTestRuntimes: ${{ parameters.netTestRuntimes }} - poolName: ADO-CI-1ES-Pool + poolName: ${{ variables.poolName }} saPassword: $(saPassword) sqlSetupStep: template: /eng/pipelines/common/templates/steps/configure-sql-server-win-step.yml@self From 73d38a11a6cc30384cbba4d1e80faba2372d9bfb Mon Sep 17 00:00:00 2001 From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com> Date: Tue, 2 Jun 2026 17:43:40 -0300 Subject: [PATCH 08/10] Removed unnecessary template parameter defaults. --- eng/pipelines/stress/stress-tests-job.yml | 5 ----- eng/pipelines/stress/stress-tests-stage.yml | 7 ++++--- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/eng/pipelines/stress/stress-tests-job.yml b/eng/pipelines/stress/stress-tests-job.yml index b0a2b90624..27e4608cae 100644 --- a/eng/pipelines/stress/stress-tests-job.yml +++ b/eng/pipelines/stress/stress-tests-job.yml @@ -24,7 +24,6 @@ parameters: # True to enable debugging steps. - name: debug type: boolean - default: false # The prefix to prepend to the job's display name: # @@ -36,7 +35,6 @@ parameters: # The verbosity level for the dotnet CLI commands. - name: dotnetVerbosity type: string - default: normal values: - quiet - minimal @@ -52,17 +50,14 @@ parameters: # When false, test failures fail the job. All test steps always run regardless of this setting. - name: warnOnTestFailure type: boolean - default: false # The list of .NET Framework runtimes to test against. - name: netFrameworkTestRuntimes type: object - default: [] # The list of .NET runtimes to test against. - name: netTestRuntimes type: object - default: [] # The name of the Azure Pipelines pool to use. - name: poolName diff --git a/eng/pipelines/stress/stress-tests-stage.yml b/eng/pipelines/stress/stress-tests-stage.yml index 901a66f21a..0ac192a601 100644 --- a/eng/pipelines/stress/stress-tests-stage.yml +++ b/eng/pipelines/stress/stress-tests-stage.yml @@ -30,18 +30,15 @@ parameters: # True to enable debugging steps. - name: debug type: boolean - default: false # When true, test failures produce warnings (SucceededWithIssues) but do not fail the job. # When false, test failures fail the job. All test steps always run regardless of this setting. - name: warnOnTestFailure type: boolean - default: false # The verbosity level for the dotnet CLI commands. - name: dotnetVerbosity type: string - default: normal values: - quiet - minimal @@ -93,6 +90,8 @@ stages: dotnetVerbosity: ${{ parameters.dotnetVerbosity }} warnOnTestFailure: ${{ parameters.warnOnTestFailure }} jobNameSuffix: linux + # No .NET Framework runtimes on Linux. + netFrameworkTestRuntimes: [] netTestRuntimes: ${{ parameters.netTestRuntimes }} poolName: ${{ variables.poolName }} saPassword: $(saPassword) @@ -137,6 +136,8 @@ stages: dotnetVerbosity: ${{ parameters.dotnetVerbosity }} warnOnTestFailure: ${{ parameters.warnOnTestFailure }} jobNameSuffix: macos + # No .NET Framework runtimes on macOS. + netFrameworkTestRuntimes: [] netTestRuntimes: ${{ parameters.netTestRuntimes }} # We don't have any 1ES Hosted Pool images for macOS, so we use a generic one from Azure # Pipelines. From 40670e7fc56cd29a2500d5d743fa07c69f50d774 Mon Sep 17 00:00:00 2001 From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com> Date: Wed, 3 Jun 2026 08:10:51 -0300 Subject: [PATCH 09/10] Added ADO.Net pipeline URL. --- eng/pipelines/stress/stress-tests-pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/pipelines/stress/stress-tests-pipeline.yml b/eng/pipelines/stress/stress-tests-pipeline.yml index e9c1f3ecb8..edd962b911 100644 --- a/eng/pipelines/stress/stress-tests-pipeline.yml +++ b/eng/pipelines/stress/stress-tests-pipeline.yml @@ -14,7 +14,7 @@ # ADO.Net project: # Triggering pipeline: MDS Main CI (branch internal/main only) # Pipeline name: sqlclient-stress -# Pipeline URL: TODO: add URL when pipeline is created +# Pipeline URL: https://dev.azure.com/SqlClientDrivers/ADO.Net/_build?definitionId=2284 # Set the pipeline run name to the day-of-year and the daily run counter. name: $(DayOfYear)$(Rev:rr) From 98f2b8998df1ae799146348ee148b14149a833e6 Mon Sep 17 00:00:00 2001 From: Paul Medynski <31868385+paulmedynski@users.noreply.github.com> Date: Wed, 3 Jun 2026 09:02:37 -0300 Subject: [PATCH 10/10] - Gave all of the stress test C# files a proper namespace. - Upgraded the Runner to use System.CommandLine instead of trying to parse arguments by hand. --- eng/pipelines/stress/stress-tests-job.yml | 2 +- .../StressTests/Directory.Packages.props | 4 + .../IMonitorLoader/IMonitorLoader.cs | 2 +- .../IMonitorLoader/MonitorMetrics.cs | 2 +- .../GlobalExceptionHandlerAttribute.cs | 2 +- .../Attributes/GlobalTestCleanupAttribute.cs | 2 +- .../Attributes/GlobalTestSetupAttribute.cs | 2 +- .../Attributes/TestAttribute.cs | 2 +- .../Attributes/TestCleanupAttribute.cs | 2 +- .../Attributes/TestSetupAttribute.cs | 2 +- .../Attributes/TestVariationAttribute.cs | 2 +- .../DeadlockDetection.cs | 2 +- .../DeadlockDetectionTaskScheduler.cs | 2 +- .../SqlClient.Stress.Common/TestMetrics.cs | 2 +- .../SqlClient.Stress.Common/VersionUtil.cs | 2 +- .../SqlClient.Stress.Framework/AsyncUtils.cs | 3 +- .../SqlClient.Stress.Framework/DataSource.cs | 2 +- .../DataStressConnection.cs | 2 +- .../DataStressErrors.cs | 2 +- .../DataStressFactory.cs | 2 +- .../DataStressReader.cs | 2 +- .../DataStressSettings.cs | 2 +- .../DataTestGroup.cs | 3 +- .../SqlClient.Stress.Framework/Extensions.cs | 2 +- .../StressConfigReader.cs | 4 +- .../TrackedRandom.cs | 2 +- .../SqlClient.Stress.Runner/Constants.cs | 2 +- .../Ex API/MemApi.Windows.cs | 2 +- .../ITestAttributeFilter.cs | 2 +- .../SqlClient.Stress.Runner/LogManager.cs | 2 +- .../Monitor/FakeConsole.cs | 2 +- .../SqlClient.Stress.Runner/Monitor/Logger.cs | 2 +- .../Monitor/MonitorLoadUtils.cs | 7 +- .../Monitor/RecordedExceptions.cs | 2 +- .../SqlClient.Stress.Runner/PerfCounters.cs | 2 +- .../SqlClient.Stress.Runner/Program.cs | 289 ++++++++++-------- .../SqlClient.Stress.Runner.csproj | 4 + .../SqlClient.Stress.Runner/StressEngine.cs | 3 +- .../SqlClient.Stress.Runner/TestFinder.cs | 2 +- .../Tests/MultithreadedTest.cs | 2 +- .../Tests/StressTest.cs | 2 +- .../SqlClient.Stress.Runner/Tests/Test.cs | 2 +- .../SqlClient.Stress.Runner/Tests/TestBase.cs | 2 +- .../Tests/ThreadPoolTest.cs | 2 +- .../FilteredDefaultTraceListener.cs | 2 +- .../HostsFileManager.cs | 2 +- .../MultiSubnetFailoverSetup.cs | 3 +- .../SqlClient.Stress.Tests/NetUtils.cs | 2 +- .../SqlClientStressFactory.cs | 3 +- .../SqlClientTestGroup.cs | 3 +- 50 files changed, 213 insertions(+), 191 deletions(-) diff --git a/eng/pipelines/stress/stress-tests-job.yml b/eng/pipelines/stress/stress-tests-job.yml index 27e4608cae..53b2f2536f 100644 --- a/eng/pipelines/stress/stress-tests-job.yml +++ b/eng/pipelines/stress/stress-tests-job.yml @@ -143,7 +143,7 @@ jobs: # Stress test options passed after the "--" separator. - name: stressTestOpts - value: -a SqlClient.Stress.Tests -console + value: --assembly SqlClient.Stress.Tests --console steps: diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/Directory.Packages.props b/src/Microsoft.Data.SqlClient/tests/StressTests/Directory.Packages.props index 1d19b81910..addc60556f 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/Directory.Packages.props +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/Directory.Packages.props @@ -9,4 +9,8 @@ true + + + + diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/IMonitorLoader/IMonitorLoader.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/IMonitorLoader/IMonitorLoader.cs index 1dcbde121f..a565889bd9 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/IMonitorLoader/IMonitorLoader.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/IMonitorLoader/IMonitorLoader.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; -namespace Monitoring +namespace Microsoft.Data.SqlClient.Test.Stress { public interface IMonitorLoader { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/IMonitorLoader/MonitorMetrics.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/IMonitorLoader/MonitorMetrics.cs index ed37544e4e..5da0395e20 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/IMonitorLoader/MonitorMetrics.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/IMonitorLoader/MonitorMetrics.cs @@ -4,7 +4,7 @@ using System; -namespace Monitoring +namespace Microsoft.Data.SqlClient.Test.Stress { public class MonitorMetrics { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/GlobalExceptionHandlerAttribute.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/GlobalExceptionHandlerAttribute.cs index 810580d9f8..cc4e5f6cc9 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/GlobalExceptionHandlerAttribute.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/GlobalExceptionHandlerAttribute.cs @@ -4,7 +4,7 @@ using System; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] public class GlobalExceptionHandlerAttribute : Attribute diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/GlobalTestCleanupAttribute.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/GlobalTestCleanupAttribute.cs index 2159d2630e..5a058fb23d 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/GlobalTestCleanupAttribute.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/GlobalTestCleanupAttribute.cs @@ -4,7 +4,7 @@ using System; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] public class GlobalTestCleanupAttribute : Attribute diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/GlobalTestSetupAttribute.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/GlobalTestSetupAttribute.cs index 00ed3d5b05..98d1c3c560 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/GlobalTestSetupAttribute.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/GlobalTestSetupAttribute.cs @@ -4,7 +4,7 @@ using System; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] public class GlobalTestSetupAttribute : Attribute diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/TestAttribute.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/TestAttribute.cs index 3146c2d808..a3af2de8a1 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/TestAttribute.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/TestAttribute.cs @@ -4,7 +4,7 @@ using System; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { public enum TestPriority { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/TestCleanupAttribute.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/TestCleanupAttribute.cs index 32bc5ee6bc..9825f98ac7 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/TestCleanupAttribute.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/TestCleanupAttribute.cs @@ -4,7 +4,7 @@ using System; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] public class TestCleanupAttribute : Attribute diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/TestSetupAttribute.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/TestSetupAttribute.cs index 5626032b69..b12254d75b 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/TestSetupAttribute.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/TestSetupAttribute.cs @@ -4,7 +4,7 @@ using System; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] public class TestSetupAttribute : Attribute diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/TestVariationAttribute.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/TestVariationAttribute.cs index e54acfa969..3277811e27 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/TestVariationAttribute.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/Attributes/TestVariationAttribute.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.Text; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { [AttributeUsage(AttributeTargets.Field, Inherited = true, AllowMultiple = true)] public class TestVariationAttribute : Attribute diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/DeadlockDetection.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/DeadlockDetection.cs index 50fc6d3d7a..b749726149 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/DeadlockDetection.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/DeadlockDetection.cs @@ -9,7 +9,7 @@ using System.Threading; using System.Threading.Tasks; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { public class DeadlockDetection { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/DeadlockDetectionTaskScheduler.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/DeadlockDetectionTaskScheduler.cs index 22a540def8..be5b44f0c9 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/DeadlockDetectionTaskScheduler.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/DeadlockDetectionTaskScheduler.cs @@ -7,7 +7,7 @@ using System.Threading; using System.Threading.Tasks; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { public class DeadlockDetectionTaskScheduler : TaskScheduler { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/TestMetrics.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/TestMetrics.cs index 054a822dc1..fbab0e4248 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/TestMetrics.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/TestMetrics.cs @@ -7,7 +7,7 @@ using System.Collections.Generic; using System.Reflection; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { public static class TestMetrics { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/VersionUtil.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/VersionUtil.cs index 1778903834..ddcc24fb85 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/VersionUtil.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Common/VersionUtil.cs @@ -8,7 +8,7 @@ #pragma warning disable 618 -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { public class VersionUtil { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/AsyncUtils.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/AsyncUtils.cs index 84f0fba0de..3d2b0cdbb5 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/AsyncUtils.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/AsyncUtils.cs @@ -8,9 +8,8 @@ using System.Runtime.ExceptionServices; using System.Threading.Tasks; using System.Xml; -using DPStressHarness; -namespace Stress.Data +namespace Microsoft.Data.SqlClient.Test.Stress { public enum SyncAsyncMode { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataSource.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataSource.cs index b61379aa0a..a83269e55e 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataSource.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataSource.cs @@ -5,7 +5,7 @@ using System; using System.Collections.Generic; -namespace Stress.Data +namespace Microsoft.Data.SqlClient.Test.Stress { /// /// supported source types - values for 'type' attribute for 'source' node in App.config diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressConnection.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressConnection.cs index 46becd4897..cd47170ead 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressConnection.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressConnection.cs @@ -8,7 +8,7 @@ using System.Threading; using System.Threading.Tasks; -namespace Stress.Data +namespace Microsoft.Data.SqlClient.Test.Stress { public class DataStressConnection : IDisposable { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressErrors.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressErrors.cs index 46b7751d50..5cc12b0dd7 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressErrors.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressErrors.cs @@ -5,7 +5,7 @@ using System; using System.Diagnostics; -namespace Stress.Data +namespace Microsoft.Data.SqlClient.Test.Stress { public enum ErrorHandlingAction { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressFactory.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressFactory.cs index 8e06a1de89..8d9ad88496 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressFactory.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressFactory.cs @@ -11,7 +11,7 @@ using System.Data.Common; using System.Diagnostics; -namespace Stress.Data +namespace Microsoft.Data.SqlClient.Test.Stress { /// /// Base class to generate utility objects required for stress tests to run. For example: connection strings, command texts, diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressReader.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressReader.cs index cad1bfa579..cee280fcf7 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressReader.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressReader.cs @@ -13,7 +13,7 @@ using System.Threading; using System.Threading.Tasks; -namespace Stress.Data +namespace Microsoft.Data.SqlClient.Test.Stress { public class DataStressReader : IDisposable { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressSettings.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressSettings.cs index 8ddf737015..ddd498fde4 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressSettings.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataStressSettings.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.Linq; -namespace Stress.Data +namespace Microsoft.Data.SqlClient.Test.Stress { /// /// Loads dataStressSettings section from Stress.Data.Framework.dll.config (App.config in source tree) diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataTestGroup.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataTestGroup.cs index ea2bfe6553..b033e664cd 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataTestGroup.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/DataTestGroup.cs @@ -12,9 +12,8 @@ using System.Threading; using System.Threading.Tasks; -using DPStressHarness; -namespace Stress.Data +namespace Microsoft.Data.SqlClient.Test.Stress { /// /// basic set of tests to run on each managed provider diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/Extensions.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/Extensions.cs index 2629bc20bb..ceccbabc94 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/Extensions.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/Extensions.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; using System.Xml; -namespace Stress.Data +namespace Microsoft.Data.SqlClient.Test.Stress { public static class Extensions { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/StressConfigReader.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/StressConfigReader.cs index 1b677f965a..db7f1957f6 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/StressConfigReader.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/StressConfigReader.cs @@ -8,9 +8,9 @@ using System.Text.Json; using System.Xml; using System.Xml.XPath; -using static Stress.Data.DataStressSettings; +using static Microsoft.Data.SqlClient.Test.Stress.DataStressSettings; -namespace Stress.Data +namespace Microsoft.Data.SqlClient.Test.Stress { /// /// Reads the configuration from a configuration file and provides the configuration diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/TrackedRandom.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/TrackedRandom.cs index b42128fff5..3b2211e5cf 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/TrackedRandom.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Framework/TrackedRandom.cs @@ -5,7 +5,7 @@ using System; using System.Collections.Generic; -namespace Stress.Data +namespace Microsoft.Data.SqlClient.Test.Stress { /// /// Random number generator that tracks information necessary to reproduce a sequence of random numbers. diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Constants.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Constants.cs index 10f0ecb41b..8edd989cef 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Constants.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Constants.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.Text; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { public static class Constants { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Ex API/MemApi.Windows.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Ex API/MemApi.Windows.cs index 053aea09a1..fd0205eabb 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Ex API/MemApi.Windows.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Ex API/MemApi.Windows.cs @@ -5,7 +5,7 @@ using System; using System.Runtime.InteropServices; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { static class MemApi { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/ITestAttributeFilter.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/ITestAttributeFilter.cs index c3afa9251d..51e54d0163 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/ITestAttributeFilter.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/ITestAttributeFilter.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { public interface ITestAttributeFilter { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/LogManager.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/LogManager.cs index 9b534a24b5..96271891dd 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/LogManager.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/LogManager.cs @@ -8,7 +8,7 @@ using System.Linq; using System.Text; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { public class LogManager: IDisposable { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Monitor/FakeConsole.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Monitor/FakeConsole.cs index f13949ae8e..b734c46d4d 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Monitor/FakeConsole.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Monitor/FakeConsole.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.Text; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { public static class FakeConsole { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Monitor/Logger.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Monitor/Logger.cs index 9226c4b930..ff9244d8b2 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Monitor/Logger.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Monitor/Logger.cs @@ -7,7 +7,7 @@ using System.Xml; using System.Diagnostics; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { public class Logger { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Monitor/MonitorLoadUtils.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Monitor/MonitorLoadUtils.cs index 80661566fa..268f9d7dbf 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Monitor/MonitorLoadUtils.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Monitor/MonitorLoadUtils.cs @@ -3,19 +3,18 @@ // See the LICENSE file in the project root for more information. using System; -using Monitoring; using System.Reflection; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { public static class MonitorLoader { public static IMonitorLoader LoadMonitorLoaderAssembly() { IMonitorLoader monitorloader = null; - const string classname = "Monitoring.MonitorLoader"; + const string classname = "Microsoft.Data.SqlClient.Test.Stress.MonitorLoader"; const string interfacename = "IMonitorLoader"; - Assembly mainAssembly = typeof(Monitoring.IMonitorLoader).GetTypeInfo().Assembly; + Assembly mainAssembly = typeof(IMonitorLoader).GetTypeInfo().Assembly; Type t = mainAssembly.GetType(classname); //make sure the type is derived from IMonitorLoader diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Monitor/RecordedExceptions.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Monitor/RecordedExceptions.cs index 72a10f4d30..36982ccde1 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Monitor/RecordedExceptions.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Monitor/RecordedExceptions.cs @@ -8,7 +8,7 @@ using System.Diagnostics; using System.Threading; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { public class RecordedExceptions { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/PerfCounters.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/PerfCounters.cs index 84a3ccfba0..307de8e1e2 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/PerfCounters.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/PerfCounters.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { public class PerfCounters { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Program.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Program.cs index ff76b4d15f..da1ce59316 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Program.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Program.cs @@ -4,174 +4,195 @@ using System; using System.Collections.Generic; +using System.CommandLine; +using System.CommandLine.Parsing; using System.IO; using System.Reflection; using Microsoft.Data.SqlClient; -namespace DPStressHarness//Microsoft.Data.SqlClient.Stress +namespace Microsoft.Data.SqlClient.Test.Stress { class Program { private static bool s_debugMode = false; + private static bool s_console = false; + private static IEnumerable s_tests; + private static StressEngine s_eng; + static int Main(string[] args) { - int exitCode = Init(args); - if (exitCode != 0) + var assemblyOption = new Option("--assembly") { - return exitCode; - } - return Run(); - } + Description = "The name of the assembly containing the tests (loaded via Assembly.Load).", + Required = true + }; - private static IEnumerable s_tests; - private static StressEngine s_eng; - private static bool s_console = false; + var overrideOption = new Option("--override") + { + Description = "Override a test property. Format: name=value", + AllowMultipleArgumentsPerToken = true + }; - public static int Init(string[] args) - { - for (int i = 0; i < args.Length; i++) + var variationOption = new Option("--variation") + { + Description = "Add a test variation.", + AllowMultipleArgumentsPerToken = true + }; + + var testOption = new Option("--test") { Description = "Run specific test(s), semicolon-separated." }; + var durationOption = new Option("--duration") { Description = "Duration of the test in seconds." }; + var threadsOption = new Option("--threads") { Description = "Number of threads to use." }; + var consoleOption = new Option("--console") { Description = "Emit all output to the console." }; + var debugOption = new Option("--debug") { Description = "Print process ID and wait for debugger attach." }; + var exceptionThresholdOption = new Option("--exception-threshold") { Description = "Limit on exceptions before test halts." }; + var monitorEnabledOption = new Option("--monitor-enabled") { Description = "Enable monitoring." }; + var randomSeedOption = new Option("--random-seed") { Description = "Seed for the random number generator." }; + var filterOption = new Option("--filter") { Description = "Run tests matching the given filter. Example: TestType=Query,Update;IsServerTest=True" }; + var printMethodNameOption = new Option("--print-method-name") { Description = "Print test method names to console." }; + var deadlockDetectionOption = new Option("--deadlock-detection") { Description = "Enable deadlock detection." }; + + var rootCommand = new RootCommand("SqlClient Stress Test Runner") + { + assemblyOption, + overrideOption, + variationOption, + testOption, + durationOption, + threadsOption, + consoleOption, + debugOption, + exceptionThresholdOption, + monitorEnabledOption, + randomSeedOption, + filterOption, + printMethodNameOption, + deadlockDetectionOption + }; + + rootCommand.SetAction((ParseResult result) => { - switch (args[i]) + // Assembly + TestFinder.AssemblyName = new AssemblyName(result.GetValue(assemblyOption)); + + // Overrides (format: name=value) + var overrides = result.GetValue(overrideOption); + if (overrides != null) { - case "-a": - string assemblyName = args[++i]; - TestFinder.AssemblyName = new AssemblyName(assemblyName); - break; - - case "-override": - TestMetrics.Overrides.Add(args[++i], args[++i]); - break; - - case "-variation": - TestMetrics.Variations.Add(args[++i]); - break; - - case "-test": - TestMetrics.SelectedTests.AddRange(args[++i].Split(';')); - break; - - case "-duration": - TestMetrics.StressDuration = int.Parse(args[++i]); - break; - - case "-threads": - TestMetrics.StressThreads = int.Parse(args[++i]); - break; - - case "-console": - s_console = true; - break; - - case "-debug": - s_debugMode = true; - if (System.Diagnostics.Debugger.IsAttached) - { - System.Diagnostics.Debugger.Break(); - } - else + foreach (var item in overrides) + { + var eqIndex = item.IndexOf('='); + if (eqIndex <= 0) { - Console.WriteLine("Current PID: {0}, attach the debugger and press Enter to continue the execution...", System.Diagnostics.Process.GetCurrentProcess().Id); - Console.ReadLine(); + Console.Error.WriteLine($"Error: --override value '{item}' must be in name=value format."); + Environment.Exit(1); } - break; + TestMetrics.Overrides.Add(item.Substring(0, eqIndex), item.Substring(eqIndex + 1)); + } + } - case "-exceptionThreshold": - TestMetrics.ExceptionThreshold = int.Parse(args[++i]); - break; + // Variations + var variations = result.GetValue(variationOption); + if (variations != null) + { + foreach (var v in variations) + { + TestMetrics.Variations.Add(v); + } + } - case "-monitorenabled": - TestMetrics.MonitorEnabled = bool.Parse(args[++i]); - break; + // Test + var test = result.GetValue(testOption); + if (test != null) + { + TestMetrics.SelectedTests.AddRange(test.Split(';')); + } - case "-randomSeed": - TestMetrics.RandomSeed = int.Parse(args[++i]); - break; + // Duration + var duration = result.GetValue(durationOption); + if (duration.HasValue) + { + TestMetrics.StressDuration = duration.Value; + } - case "-filter": - TestMetrics.Filter = args[++i]; - break; + // Threads + var threads = result.GetValue(threadsOption); + if (threads.HasValue) + { + TestMetrics.StressThreads = threads.Value; + } - case "-printMethodName": - TestMetrics.PrintMethodName = true; - break; + // Console + s_console = result.GetValue(consoleOption); - case "-deadlockdetection": - if (bool.Parse(args[++i])) - { - DeadlockDetection.Enable(); - } - break; + // Debug + s_debugMode = result.GetValue(debugOption); + if (s_debugMode) + { + if (System.Diagnostics.Debugger.IsAttached) + { + System.Diagnostics.Debugger.Break(); + } + else + { + Console.WriteLine("Current PID: {0}, attach the debugger and press Enter to continue the execution...", System.Diagnostics.Process.GetCurrentProcess().Id); + Console.ReadLine(); + } + } - default: - PrintHelp(args); - return 1; + // Exception threshold + var threshold = result.GetValue(exceptionThresholdOption); + if (threshold.HasValue) + { + TestMetrics.ExceptionThreshold = threshold.Value; } - } - PrintConfigSummary(); + // Monitor enabled + var monitor = result.GetValue(monitorEnabledOption); + if (monitor.HasValue) + { + TestMetrics.MonitorEnabled = monitor.Value; + } - if (TestFinder.AssemblyName != null) - { - Console.WriteLine("Assembly Found for the Assembly Name " + TestFinder.AssemblyName); + // Random seed + var seed = result.GetValue(randomSeedOption); + if (seed.HasValue) + { + TestMetrics.RandomSeed = seed.Value; + } - // get and load all the tests - s_tests = TestFinder.GetTests(Assembly.Load(TestFinder.AssemblyName)); + // Filter + var filter = result.GetValue(filterOption); + if (filter != null) + { + TestMetrics.Filter = filter; + } - // instantiate the stress engine - s_eng = new StressEngine(TestMetrics.StressThreads, TestMetrics.StressDuration, s_tests, TestMetrics.RandomSeed); - } - else - { - Console.Error.WriteLine("Error: No assembly specified. Use -a ."); - PrintHelp(args); - return 1; - } + // Print method name + TestMetrics.PrintMethodName = result.GetValue(printMethodNameOption); - return 0; - } + // Deadlock detection + if (result.GetValue(deadlockDetectionOption)) + { + DeadlockDetection.Enable(); + } - private static void PrintHelp(string[] args) - { - Console.WriteLine($"Arguments ({args.Length}):"); - for (int i = 0; i < args.Length; i++) + // Print config, load tests, and run + PrintConfigSummary(); + + Console.WriteLine("Assembly Found for the Assembly Name " + TestFinder.AssemblyName); + s_tests = TestFinder.GetTests(Assembly.Load(TestFinder.AssemblyName)); + s_eng = new StressEngine(TestMetrics.StressThreads, TestMetrics.StressDuration, s_tests, TestMetrics.RandomSeed); + }); + + var parseResult = rootCommand.Parse(args); + int exitCode = parseResult.Invoke(); + if (exitCode != 0 || s_eng == null) { - Console.WriteLine($" [{i}] \"{args[i]}\""); + return exitCode; } - Console.WriteLine(); - Console.WriteLine("stresstest.exe [-a ] "); - Console.WriteLine(); - Console.WriteLine(" -a should specify path to the assembly containing the tests."); - Console.WriteLine(); - Console.WriteLine("Supported options are:"); - Console.WriteLine(); - Console.WriteLine(" -duration Duration of the test in seconds."); - Console.WriteLine(); - Console.WriteLine(" -threads Number of threads to use."); - Console.WriteLine(); - Console.WriteLine(" -override Override the value of a test property."); - Console.WriteLine(); - Console.WriteLine(" -test Run specific test(s)."); - Console.WriteLine(); - Console.WriteLine(" -console Emit all output to the console."); - Console.WriteLine(); - Console.WriteLine(" -debug Print process ID in the beginning and wait for Enter (to give your time to attach the debugger)."); - Console.WriteLine(); - Console.WriteLine(" -exceptionThreshold An optional limit on exceptions which will be caught. When reached, test will halt."); - Console.WriteLine(); - Console.WriteLine(" -monitorenabled True or False to enable monitoring. Default is false"); - Console.WriteLine(); - Console.WriteLine(" -randomSeed Enables setting of the random number generator used internally. This serves both the purpose"); - Console.WriteLine(" of helping to improve reproducibility and making it deterministic from Chess's perspective"); - Console.WriteLine(" for a given schedule. Default is " + TestMetrics.RandomSeed + "."); - Console.WriteLine(); - Console.WriteLine(" -filter Run tests whose stress test attributes match the given filter. Filter is not applied if attribute"); - Console.WriteLine(" does not implement ITestAttributeFilter. Example: -filter TestType=Query,Update;IsServerTest=True "); - Console.WriteLine(); - Console.WriteLine(" -printMethodName Print tests' title in console window"); - Console.WriteLine(); - Console.WriteLine(" -deadlockdetection True or False to enable deadlock detection. Default is false"); - Console.WriteLine(); + + return Run(); } private static void PrintConfigSummary() diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/SqlClient.Stress.Runner.csproj b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/SqlClient.Stress.Runner.csproj index d0c325fcef..8a2bc08b4c 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/SqlClient.Stress.Runner.csproj +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/SqlClient.Stress.Runner.csproj @@ -5,6 +5,10 @@ stresstest + + + + diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/StressEngine.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/StressEngine.cs index 349b5c0539..f20b9104d1 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/StressEngine.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/StressEngine.cs @@ -6,9 +6,8 @@ using System.Collections.Generic; using System.Threading; using System.Diagnostics; -using Monitoring; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { public class StressEngine { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/TestFinder.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/TestFinder.cs index 3f18c6df43..498964c132 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/TestFinder.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/TestFinder.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.Reflection; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { internal class TestFinder { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/MultithreadedTest.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/MultithreadedTest.cs index 01ea961426..1fe985936b 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/MultithreadedTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/MultithreadedTest.cs @@ -8,7 +8,7 @@ using System.Diagnostics; using System.Threading; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { internal class MultiThreadedTest : TestBase { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/StressTest.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/StressTest.cs index c2637d5e5d..a96838b4f5 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/StressTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/StressTest.cs @@ -9,7 +9,7 @@ using System.Diagnostics; using System.Runtime.InteropServices; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { internal class StressTest : TestBase { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/Test.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/Test.cs index a73448a30b..35353ec7bf 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/Test.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/Test.cs @@ -7,7 +7,7 @@ using System.Reflection; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { internal class Test : TestBase { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/TestBase.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/TestBase.cs index 95546547da..3cc2dac8bf 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/TestBase.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/TestBase.cs @@ -6,7 +6,7 @@ using System.Collections.Generic; using System.Reflection; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { public abstract class TestBase { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/ThreadPoolTest.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/ThreadPoolTest.cs index f065c15312..c52125ea7e 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/ThreadPoolTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Runner/Tests/ThreadPoolTest.cs @@ -10,7 +10,7 @@ using System.Runtime.InteropServices; using System.Threading; -namespace DPStressHarness +namespace Microsoft.Data.SqlClient.Test.Stress { internal class ThreadPoolTest : TestBase { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/FilteredDefaultTraceListener.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/FilteredDefaultTraceListener.cs index ce29f8ee29..0e102fedef 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/FilteredDefaultTraceListener.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/FilteredDefaultTraceListener.cs @@ -7,7 +7,7 @@ using System.Reflection; using System.Text.RegularExpressions; -namespace Stress.Data.SqlClient +namespace Microsoft.Data.SqlClient.Test.Stress { /// /// A DefaultTraceListener that can filter out given asserts diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/HostsFileManager.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/HostsFileManager.cs index 6d44909ddb..7c665ee516 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/HostsFileManager.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/HostsFileManager.cs @@ -12,7 +12,7 @@ using System.Diagnostics; using System.Runtime.InteropServices; -namespace Microsoft.Test.Data.SqlClient +namespace Microsoft.Data.SqlClient.Test.Stress { /// /// allows user to manipulate %windir%\system32\drivers\etc\hosts diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/MultiSubnetFailoverSetup.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/MultiSubnetFailoverSetup.cs index 2a0719d201..9fb1f9b5bb 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/MultiSubnetFailoverSetup.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/MultiSubnetFailoverSetup.cs @@ -2,14 +2,13 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Microsoft.Test.Data.SqlClient; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Threading.Tasks; -namespace Stress.Data.SqlClient +namespace Microsoft.Data.SqlClient.Test.Stress { internal class MultiSubnetFailoverSetup { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/NetUtils.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/NetUtils.cs index 0e756d1bf9..c3bac5b53d 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/NetUtils.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/NetUtils.cs @@ -9,7 +9,7 @@ using System.Collections.Generic; using System.Threading.Tasks; -namespace Microsoft.Test.Data.SqlClient +namespace Microsoft.Data.SqlClient.Test.Stress { public static class NetUtils { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/SqlClientStressFactory.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/SqlClientStressFactory.cs index 7aec9d461a..32db797c97 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/SqlClientStressFactory.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/SqlClientStressFactory.cs @@ -6,9 +6,8 @@ using System.Collections.Generic; using System.Diagnostics; using Microsoft.Data.SqlClient; -using Microsoft.Test.Data.SqlClient; -namespace Stress.Data.SqlClient +namespace Microsoft.Data.SqlClient.Test.Stress { public class SqlClientStressFactory : DataStressFactory { diff --git a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/SqlClientTestGroup.cs b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/SqlClientTestGroup.cs index 7c7597ba8a..b524a15a14 100644 --- a/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/SqlClientTestGroup.cs +++ b/src/Microsoft.Data.SqlClient/tests/StressTests/SqlClient.Stress.Tests/SqlClientTestGroup.cs @@ -11,10 +11,9 @@ using Microsoft.Data.SqlClient; using System.Xml; -using DPStressHarness; using System.IO; -namespace Stress.Data.SqlClient +namespace Microsoft.Data.SqlClient.Test.Stress { public class SqlClientTestGroup : DataTestGroup {