# Setup

This guide covers prerequisites, building, running, and testing the NATS .NET server.

## Prerequisites

### .NET 10 SDK

The project targets `net10.0` with `LangVersion preview` (configured in `Directory.Build.props`). Install the .NET 10 preview SDK from https://dotnet.microsoft.com/download.

Verify your installation:

```bash
dotnet --version
# Expected: 10.0.x
```

### Go Toolchain (optional)

The Go toolchain is only needed if you want to run the reference server from `golang/nats-server/` or execute Go test suites for cross-validation. It is not required for building or testing the .NET port.

```bash
go version
# Expected: go1.22 or later
```

---

## Building

The solution file uses the `.slnx` format (not `.sln`). Pass it explicitly if your tooling requires it.

```bash
# Build all projects
dotnet build

# Clean and rebuild
dotnet clean && dotnet build
```

The solution contains three projects:

| Project | Path |
|---------|------|
| `NATS.Server` | `src/NATS.Server/` |
| `NATS.Server.Host` | `src/NATS.Server.Host/` |
| `NATS.Server.Tests` | `tests/NATS.Server.Tests/` |

All projects share settings from `Directory.Build.props`: `net10.0` target framework, nullable reference types enabled, warnings treated as errors.

---

## Running

The server executable is `NATS.Server.Host`. With no arguments it binds to `0.0.0.0:4222`.

```bash
dotnet run --project src/NATS.Server.Host
```

### CLI Arguments

| Flag | Alias | Type | Default | Description |
|------|-------|------|---------|-------------|
| `-p` | `--port` | `int` | `4222` | TCP port to listen on |
| `-a` | `--addr` | `string` | `0.0.0.0` | Bind address |
| `-n` | `--name` | `string` | `nats-dotnet-<hostname>` | Server name reported in INFO |

```bash
# Custom port
dotnet run --project src/NATS.Server.Host -- -p 14222

# Custom address and name
dotnet run --project src/NATS.Server.Host -- -a 127.0.0.1 -p 4222 -n dev-server
```

The `--` separator is required to pass arguments through `dotnet run` to the application.

Startup log output (Serilog console sink):

```
[12:00:00 INF] Listening on 0.0.0.0:4222
```

---

## Testing

```bash
# Run all tests
dotnet test

# Run tests with verbose output
dotnet test -v normal

# Run a single test project
dotnet test tests/NATS.Server.Tests

# Run a specific test by name
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~SubListTests"
```

### Test Stack

| Package | Version | Purpose |
|---------|---------|---------|
| `xunit` (xUnit 3) | 2.9.3 | Test framework |
| `xunit.runner.visualstudio` | 3.1.4 | VS/Rider test runner integration |
| `Shouldly` | 4.3.0 | Assertion library |
| `NSubstitute` | 5.3.0 | Mocking |
| `NATS.Client.Core` | 2.7.2 | Official NATS .NET client for integration tests |
| `coverlet.collector` | 6.0.4 | Code coverage |

Do not use FluentAssertions or Moq — the project uses Shouldly and NSubstitute exclusively.

### Test Files

The test project contains 100 test files organised by subsystem. Authentication and TLS tests cover token, username/password, NKey, JWT, and OCSP authenticators, account isolation, client permissions, TLS connection wrapping, and TLS rate limiting (`AuthProtocolTests.cs`, `AuthServiceTests.cs`, `AuthIntegrationTests.cs`, `AccountIsolationTests.cs`, `NKeyAuthenticatorTests.cs`, `JwtAuthenticatorTests.cs`, `TlsServerTests.cs`, `TlsHelperTests.cs`, `TlsConnectionWrapperTests.cs`, `TlsMapAuthenticatorTests.cs`, `TlsRateLimiterTests.cs`, and related files). JetStream and RAFT tests cover stream and consumer APIs, publish, pull and push consumers, ack and redelivery, retention policies, mirror/source replication, cluster reload, JWT limits, RAFT election, replication, and snapshot catchup (`JetStreamStreamApiTests.cs`, `JetStreamConsumerApiTests.cs`, `JetStreamPublishTests.cs`, `JetStreamPullConsumerTests.cs`, `JetStreamPushConsumerTests.cs`, `RaftElectionTests.cs`, `RaftReplicationTests.cs`, `RaftSnapshotCatchupTests.cs`, and related files). Clustering and routing tests cover route handshake, subscription propagation, gateway and leaf node bootstrap, cluster JetStream config, and response routing (`RouteHandshakeTests.cs`, `RouteSubscriptionPropagationTests.cs`, `GatewayLeafBootstrapTests.cs`, `ResponseRoutingTests.cs`). Monitoring and configuration tests cover config file parsing and reloading, options processing, monitoring endpoints, account stats, server stats, and subject-transform config (`MonitorTests.cs`, `NatsConfParserTests.cs`, `ConfigReloadTests.cs`, `ConfigProcessorTests.cs`, `SubjectTransformTests.cs`, and related files). WebSocket tests cover frame read/write, compression, upgrade handshake, origin checking, and integration (`WebSocket/WsFrameReadTests.cs`, `WebSocket/WsFrameWriterTests.cs`, `WebSocket/WsCompressionTests.cs`, `WebSocket/WsUpgradeTests.cs`, `WebSocket/WsIntegrationTests.cs`, and related files). Protocol and parser tests cover `NatsParser.TryParse` for each command type, header parsing, subject matching, and the `SubList` trie (`ParserTests.cs`, `NatsHeaderParserTests.cs`, `SubjectMatchTests.cs`, `SubListTests.cs`). Client lifecycle tests cover command dispatch, subscription tracking, write loop, verbose mode, no-responders, trace mode, client flags, and closed-reason handling (`ClientTests.cs`, `WriteLoopTests.cs`, `VerboseModeTests.cs`, `ClientFlagsTests.cs`, `ClientClosedReasonTests.cs`, and related files). Integration tests run end-to-end scenarios against a live server instance using `NATS.Client.Core` (`IntegrationTests.cs`, `AuthIntegrationTests.cs`, `NKeyIntegrationTests.cs`, `PermissionIntegrationTests.cs`, `SubjectTransformIntegrationTests.cs`, `ConfigIntegrationTests.cs`, `WebSocket/WsIntegrationTests.cs`).

---

## NuGet: Central Package Management

Package versions are defined centrally in `Directory.Packages.props`. Individual `.csproj` files reference packages without a `Version` attribute:

```xml
<!-- Directory.Packages.props -->
<PackageVersion Include="Shouldly" Version="4.3.0" />
<PackageVersion Include="NSubstitute" Version="5.3.0" />
```

```xml
<!-- NATS.Server.Tests.csproj -->
<PackageReference Include="Shouldly" />
<PackageReference Include="NSubstitute" />
```

To add a new dependency: add a `<PackageVersion>` entry in `Directory.Packages.props`, then add a `<PackageReference>` (without `Version`) in the relevant `.csproj`.

---

## Logging

The host configures Serilog via `Microsoft.Extensions.Logging` in `Program.cs`:

```csharp
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .Enrich.FromLogContext()
    .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}")
    .CreateLogger();

using var loggerFactory = new Serilog.Extensions.Logging.SerilogLoggerFactory(Log.Logger);
var server = new NatsServer(options, loggerFactory);
```

`NatsServer` and `NatsClient` receive `ILoggerFactory` and `ILogger` respectively via constructor injection. The core library (`NATS.Server`) depends only on `Microsoft.Extensions.Logging.Abstractions` — it has no direct Serilog dependency. The Serilog packages are wired in `NATS.Server.Host`.

Per-client loggers are created with a scoped category name that includes the client ID:

```csharp
var clientLogger = _loggerFactory.CreateLogger($"NATS.Server.NatsClient[{clientId}]");
```

To adjust log levels at runtime, modify the `LoggerConfiguration` in `Program.cs`.

---

## Related Documentation

- [Architecture](./Architecture.md)
- [Configuration Overview](../Configuration/Overview.md)
- [Protocol Overview](../Protocol/Overview.md)
- [Server Overview](../Server/Overview.md)

<!-- Last verified against codebase: 2026-02-23 -->
