Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ The Azure CLI provides different commands to assign a user-assigned managed iden
az containerapp identity assign \
--resource-group <resource-group-name> \
--name <containerapp-name> \
--identities <user-assigned-identity-resource-id>
--user-assigned <user-assigned-identity-resource-id>
```

For Azure Virtual Machines, use the Azure CLI command [`az vm identity assign`](/cli/azure/vm/identity#az-vm-identity-assign):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ The `Workers` property specifies the maximum number of threads for parallel exec
> You can also configure parallelization through [runsettings](unit-testing-mstest-configure.md#mstest-element) or [testconfig.json](unit-testing-mstest-configure.md#testconfigjson) without modifying code.
> [!TIP]
> Enable parallelization at the assembly level by default, even if many tests currently require sequential execution. This approach encourages writing new tests that support parallel execution from the start. Use the [MSTEST0001](mstest-analyzers/mstest0001.md) analyzer to ensure that every test class explicitly declares its parallelization intent, which forces you to review whether each class safely supports concurrent execution. Often, excluding just a few classes or methods with `DoNotParallelize` is sufficient, allowing the majority of your tests to run in parallel for significantly faster test execution.
> Enable parallelization at the assembly level by default, even if many tests currently require sequential execution. This approach encourages writing new tests that support parallel execution from the start. Use the [MSTEST0001](mstest-analyzers/mstest0001.md) analyzer to ensure that the assembly explicitly declares its parallelization intent with `[assembly: Parallelize]` or `[assembly: DoNotParallelize]`. Once parallelization is enabled, review each test class to determine whether it safely supports concurrent execution. Often, excluding just a few classes or methods with `DoNotParallelize` is sufficient, allowing the majority of your tests to run in parallel for significantly faster test execution.
### `DoNotParallelizeAttribute`

Expand Down
50 changes: 24 additions & 26 deletions docs/core/testing/unit-testing-mstest-writing-tests-data-driven.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ MSTest provides several attributes for data-driven testing:
|-----------|----------|----------|
| [`DataRow`](#datarowattribute) | Inline test data | Simple, static test cases |
| [`DynamicData`](#dynamicdataattribute) | Data from methods, properties, or fields | Complex or computed test data |
| [`TestDataRow<T>`](#testdatarow) | Enhanced data with metadata | Test cases needing display names or categories |
| [`DataSource`](#datasourceattribute) | External data files or databases | Legacy scenarios with external data sources |
| [`ITestDataSource`](#itestdatasource) | Custom data source attributes | Fully custom data-driven scenarios |

MSTest also provides the following types to extend data-driven scenarios:

- [`TestDataRow<T>`](#testdatarow): A return type for `ITestDataSource` implementations (including `DynamicData`) that adds metadata support such as display names, categories, and ignore messages to individual test cases.
- [`ITestDataSource`](#itestdatasource): An interface you can implement on a custom attribute to create fully custom data source attributes.

> [!TIP]
> For combinatorial testing (testing all combinations of multiple parameter sets), use the open-source [Combinatorial.MSTest](https://www.nuget.org/packages/Combinatorial.MSTest) NuGet package. This community-maintained package is [available on GitHub](https://github.com/Youssef1313/Combinatorial.MSTest) but isn't maintained by Microsoft.
Expand Down Expand Up @@ -237,10 +240,10 @@ Specify a different class using the type parameter:
```csharp
public class TestDataProvider
{
public static IEnumerable<object[]> GetTestData()
public static IEnumerable<(int, string)> GetTestData()
{
yield return new object[] { 1, "first" };
yield return new object[] { 2, "second" };
yield return (1, "first");
yield return (2, "second");
}
}

Expand Down Expand Up @@ -273,10 +276,10 @@ public class DynamicDataDisplayNameExample
Assert.IsTrue(value1 > 0);
}

public static IEnumerable<object[]> GetTestData()
public static IEnumerable<(int, string)> GetTestData()
{
yield return new object[] { 1, "first" };
yield return new object[] { 2, "second" };
yield return (1, "first");
yield return (2, "second");
}

public static string GetDisplayName(MethodInfo methodInfo, object[] data)
Expand Down Expand Up @@ -307,10 +310,10 @@ public class IgnoreDynamicDataExample
// All test cases from GetTestData are skipped
}

public static IEnumerable<object[]> GetTestData()
public static IEnumerable<(int, string)> GetTestData()
{
yield return new object[] { 1, "first" };
yield return new object[] { 2, "second" };
yield return (1, "first");
yield return (2, "second");
}
}
```
Expand Down Expand Up @@ -340,20 +343,20 @@ public class TestDataRowExample
Assert.IsTrue(value1 > 0);
}

public static IEnumerable<TestDataRow> GetTestDataRows()
public static IEnumerable<TestDataRow<(int, string)>> GetTestDataRows()
{
yield return new TestDataRow((1, "first"))
yield return new TestDataRow<(int, string)>((1, "first"))
{
DisplayName = "Test Case 1: Basic scenario",
};

yield return new TestDataRow((2, "second"))
yield return new TestDataRow<(int, string)>((2, "second"))
{
DisplayName = "Test Case 2: Edge case",
TestCategories = ["HighPriority", "Critical"],
};

yield return new TestDataRow((3, "third"))
yield return new TestDataRow<(int, string)>((3, "third"))
{
IgnoreMessage = "Not yet implemented",
};
Expand Down Expand Up @@ -511,27 +514,22 @@ For most scenarios, the default `Auto` behavior provides the best balance. Consi
public class UnfoldingExample
{
[TestMethod(UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Unfold)] // That's the default behavior
[DataRow(1)]
[DataRow(2)]
[DataRow(3)]
[DataRow(1, "one")]
[DataRow(2, "two")]
[DataRow(3, "three")]
public void TestMethodWithUnfolding(int value, string text)
{
// Each test case appears individually in Test Explorer
}

[TestMethod(UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Fold)]
[DynamicData(nameof(GetData))]
[DataRow(1, "one")]
[DataRow(2, "two")]
[DataRow(3, "three")]
public void TestMethodWithFolding(int value, string text)
{
// All test cases appear as a single collapsed node
}

public static IEnumerable<(int, string)> GetData()
{
yield return (1, "one");
yield return (2, "two");
yield return (3, "three");
}
}
```

Expand Down
8 changes: 4 additions & 4 deletions docs/fundamentals/code-analysis/configuration-options.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Configure code analysis rules
description: Learn how to configure code analysis rules in an analyzer configuration file.
ms.date: 12/06/2021
ms.date: 02/13/2026
no-loc: ["EditorConfig"]
---
# Configuration options for code analysis
Expand Down Expand Up @@ -30,7 +30,7 @@ For additional options, see [Code analysis properties](../../core/project-sdk/ms

### Analysis mode

While the .NET SDK includes all code analysis rules, only some of them are [enabled by default](https://github.com/dotnet/roslyn-analyzers/blob/main/src/NetAnalyzers/Core/AnalyzerReleases.Shipped.md). The *analysis mode* determines which, if any, set of rules to enable. You can choose a more aggressive analysis mode where most or all rules are enabled. Or you can choose a more conservative analysis mode where most or all rules are disabled, and you can then opt-in to specific rules as needed. Set your analysis mode by adding the [`<AnalysisMode>`](../../core/project-sdk/msbuild-props.md#analysismode) MSBuild property to your project file.
While the .NET SDK includes all code analysis rules, only some of them are [enabled by default](https://github.com/dotnet/sdk/blob/main/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/AnalyzerReleases.Shipped.md). The *analysis mode* determines which, if any, set of rules to enable. You can choose a more aggressive analysis mode where most or all rules are enabled. Or you can choose a more conservative analysis mode where most or all rules are disabled, and you can then opt-in to specific rules as needed. Set your analysis mode by adding the [`<AnalysisMode>`](../../core/project-sdk/msbuild-props.md#analysismode) MSBuild property to your project file.

```xml
<PropertyGroup>
Expand Down Expand Up @@ -85,7 +85,7 @@ The following table shows the different rule severities that you can configure f
| `suggestion` | Violations appear as build *messages* and as suggestions in the Visual Studio IDE. (In Visual Studio, suggestions appear as three gray dots under the first two characters.) |
| `silent` | Violations aren't visible to the user.<br/><br/>However, for code-style rules, Visual Studio code-generation features still generate code in this style. These rules also participate in cleanup and appear in the **Quick Actions and Refactorings** menu in Visual Studio. |
| `none` | Rule is suppressed completely.<br/><br/>However, for code-style rules, Visual Studio code-generation features still generate code in this style. |
| `default` | The default severity of the rule is used. The default severities for each .NET release are listed in the [roslyn-analyzers repo](https://github.com/dotnet/roslyn-analyzers/blob/main/src/NetAnalyzers/Core/AnalyzerReleases.Shipped.md). In that table, "Disabled" corresponds to `none`, "Hidden" corresponds to `silent`, and "Info" corresponds to `suggestion`. |
| `default` | The default severity of the rule is used. The default severities for each .NET release are listed in the [dotnet/sdk repo](https://github.com/dotnet/sdk/blob/main/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/AnalyzerReleases.Shipped.md). In that table, "Disabled" corresponds to `none`, "Hidden" corresponds to `silent`, and "Info" corresponds to `suggestion`. |

#### Scope

Expand Down Expand Up @@ -116,7 +116,7 @@ The following table shows the different rule severities that you can configure f
```

> [!IMPORTANT]
> When you configure the severity level for multiple rules with a single entry, either for a *category* of rules or for *all* rules, the severity only applies to rules that are [enabled by default](https://github.com/dotnet/roslyn-analyzers/blob/main/src/NetAnalyzers/Core/AnalyzerReleases.Shipped.md). And if you enable all rules by using the MSBuild properties [`<AnalysisMode>`](../../core/project-sdk/msbuild-props.md#analysismode) or [`<AnalysisLevel>`](../../core/project-sdk/msbuild-props.md#analysislevel), any bulk `dotnet_analyzer_diagnostic` options are ignored. For this reason, it's better to enable a category of rules by setting [\<AnalysisMode\<Category>>](../../core/project-sdk/msbuild-props.md#analysismodecategory) to `All`.
> When you configure the severity level for multiple rules with a single entry, either for a *category* of rules or for *all* rules, the severity only applies to rules that are [enabled by default](https://github.com/dotnet/sdk/blob/main/src/Microsoft.CodeAnalysis.NetAnalyzers/src/Microsoft.CodeAnalysis.NetAnalyzers/AnalyzerReleases.Shipped.md). And if you enable all rules by using the MSBuild properties [`<AnalysisMode>`](../../core/project-sdk/msbuild-props.md#analysismode) or [`<AnalysisLevel>`](../../core/project-sdk/msbuild-props.md#analysislevel), any bulk `dotnet_analyzer_diagnostic` options are ignored. For this reason, it's better to enable a category of rules by setting [\<AnalysisMode\<Category>>](../../core/project-sdk/msbuild-props.md#analysismodecategory) to `All`.

> [!NOTE]
> The prefix for setting severity for a single rule, `dotnet_diagnostic`, is different than the prefix for configuring severity via category or for all rules, `dotnet_analyzer_diagnostic`.
Expand Down
43 changes: 23 additions & 20 deletions docs/orleans/host/monitoring/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,36 +315,42 @@ The following table shows a collection of transaction meters used to monitor the
| `orleans-transactions-failed` | <xref:System.Diagnostics.Metrics.ObservableCounter%601> | An observable counter representing the number of failed transactions. |
| `orleans-transactions-throttled` | <xref:System.Diagnostics.Metrics.ObservableCounter%601> | An observable counter representing the number of throttled transactions. |

### Prometheus
### Export metrics

Various third-party metrics providers are available for use with Orleans. One popular example is [Prometheus](https://prometheus.io), which you can use to collect metrics from your app with OpenTelemetry.
Various third-party metrics providers are available for use with Orleans. Export metrics from your app using the [OpenTelemetry Protocol (OTLP)](https://opentelemetry.io/docs/specs/otlp/). Many observability platforms consume OTLP data directly or through an OpenTelemetry Collector, including [Prometheus](https://prometheus.io), Grafana, and Azure Monitor.

To use OpenTelemetry and Prometheus with Orleans, call the following <xref:Microsoft.Extensions.DependencyInjection.IServiceCollection> extension method:
To export metrics using OTLP with Orleans, install the [OpenTelemetry.Exporter.OpenTelemetryProtocol](https://www.nuget.org/packages/OpenTelemetry.Exporter.OpenTelemetryProtocol/) NuGet package and call the following <xref:Microsoft.Extensions.DependencyInjection.IServiceCollection> extension method:

```csharp
builder.Services.AddOpenTelemetry()
.WithMetrics(metrics =>
{
metrics
.AddPrometheusExporter()
.AddOtlpExporter()
.AddMeter("Microsoft.Orleans");
});
```

> [!IMPORTANT]
> Both the [OpenTelemetry.Exporter.Prometheus](https://www.nuget.org/packages/OpenTelemetry.Exporter.Prometheus) and [OpenTelemetry.Exporter.Prometheus.AspNetCore](https://www.nuget.org/packages/OpenTelemetry.Exporter.Prometheus.AspNetCore) NuGet packages are currently in preview as release candidates. They're not recommended for production use.
The `AddOtlpExporter` method ensures the OTLP exporter is added to the `builder`. Orleans uses a <xref:System.Diagnostics.Metrics.Meter> named `"Microsoft.Orleans"` to create <xref:System.Diagnostics.Metrics.Counter%601> instances for many Orleans-specific metrics. Use the `AddMeter` method to specify the name of the meter to subscribe to, in this case, `"Microsoft.Orleans"`.

The `AddPrometheusExporter` method ensures the `PrometheusExporter` is added to the `builder`. Orleans uses a <xref:System.Diagnostics.Metrics.Meter> named `"Microsoft.Orleans"` to create <xref:System.Diagnostics.Metrics.Counter%601> instances for many Orleans-specific metrics. Use the `AddMeter` method to specify the name of the meter to subscribe to, in this case, `"Microsoft.Orleans"`.

After configuring the exporter and building your app, call `MapPrometheusScrapingEndpoint` on the `IEndpointRouteBuilder` (the `app` instance) to expose the metrics to Prometheus. For example:
You can configure the OTLP exporter endpoint and other options as needed. For example:

```csharp
WebApplication app = builder.Build();

app.MapPrometheusScrapingEndpoint();
app.Run();
builder.Services.AddOpenTelemetry()
.WithMetrics(metrics =>
{
metrics
.AddOtlpExporter(options =>
{
options.Endpoint = new Uri("http://localhost:4317");
})
.AddMeter("Microsoft.Orleans");
});
```

> [!NOTE]
> The default OTLP exporter configuration uses gRPC (typically port `4317`). To export metrics to Prometheus, send telemetry through an OpenTelemetry Collector or configure OTLP/HTTP settings instead.

## Distributed tracing

Distributed tracing is a set of tools and practices for monitoring and troubleshooting distributed applications. It's a key component of observability and a critical tool for understanding your app's behavior. Orleans supports distributed tracing with [OpenTelemetry](https://opentelemetry.io).
Expand All @@ -356,7 +362,7 @@ Regardless of the distributed tracing exporter you choose, call:

Or set the `EnableDistributedTracing` config option to `true`.

Referring back to the [Orleans GPS Tracker sample app](/samples/dotnet/samples/orleans-gps-device-tracker-sample), you can use the [Zipkin](https://zipkin.io) distributed tracing system to monitor the app by updating _Program.cs_. To use OpenTelemetry and Zipkin with Orleans, call the following <xref:Microsoft.Extensions.DependencyInjection.IServiceCollection> extension method:
Referring back to the [Orleans GPS Tracker sample app](/samples/dotnet/samples/orleans-gps-device-tracker-sample), you can export distributed traces using the [OpenTelemetry Protocol (OTLP)](https://opentelemetry.io/docs/specs/otlp/). To use OpenTelemetry with OTLP and Orleans, install the [OpenTelemetry.Exporter.OpenTelemetryProtocol](https://www.nuget.org/packages/OpenTelemetry.Exporter.OpenTelemetryProtocol/) NuGet package and call the following <xref:Microsoft.Extensions.DependencyInjection.IServiceCollection> extension method in _Program.cs_:

```csharp
builder.Services.AddOpenTelemetry()
Expand All @@ -370,17 +376,14 @@ builder.Services.AddOpenTelemetry()
tracing.AddSource("Microsoft.Orleans.Runtime");
tracing.AddSource("Microsoft.Orleans.Application");

tracing.AddZipkinExporter(zipkin =>
tracing.AddOtlpExporter(otlp =>
{
zipkin.Endpoint = new Uri("http://localhost:9411/api/v2/spans");
otlp.Endpoint = new Uri("http://localhost:4317");
});
});
```

> [!IMPORTANT]
> The [OpenTelemetry.Exporter.Zipkin](https://www.nuget.org/packages/OpenTelemetry.Exporter.Zipkin) NuGet package is currently in preview as a release candidate. It is not recommended for production use.

The Zipkin trace is shown in the Jaeger UI (an alternative to Zipkin that uses the same data format):
The OTLP exporter works with many observability backends including Jaeger, Zipkin, Grafana Tempo, and Azure Monitor. The traces can be visualized in tools like Jaeger UI:

:::image type="content" source="../media/jaeger-ui.png" lightbox="../media/jaeger-ui.png" alt-text="Orleans GPS Tracker sample app: Jaeger UI trace.":::

Expand Down