This guide covers running the release tests both **locally** (against a local Kubernetes cluster) and **on Google Kubernetes Engine** (or any remote Kubernetes cluster).
1. Install [.NET 10.0+](https://dotnet.microsoft.com/download). (If you install a newer version, update all `net10.0` references in the `.csproj` files to match.)
3. Enable Kubernetes in Docker Desktop: **Settings → Kubernetes → Enable Kubernetes (kubeadm) → Apply & Restart**. This may take a few minutes.
> **Note on Kubernetes client compatibility:** The `KubernetesClient` package version in the `KubernetesWorkflow` project [must be compatible](https://github.com/kubernetes-client/csharp#version-compatibility) with the Kubernetes version that kubeadm exposes. For example, if kubeadm exposes Kubernetes `1.34.1`, then `KubernetesClient` must be version `18.x`.
### How it works
When you run `dotnet test` from your machine, the framework detects it is running **outside** the cluster (by checking whether the `KUBERNETES_PORT` and `KUBERNETES_SERVICE_HOST` environment variables are set). In this mode it connects to the cluster via your local `~/.kube/config`, which Docker Desktop automatically configures.
Each test creates its own isolated namespace in the cluster, starts the required Storage nodes as pods, runs the test, then tears everything down.
### Verify the cluster is working
Before running tests, confirm Docker Desktop's Kubernetes context is active:
```bash
kubectl config current-context # should show "docker-desktop"
kubectl get nodes # should show a Ready node
```
If the current context is not `docker-desktop` (e.g. it points to a remote cluster), switch it:
```bash
kubectl config use-context docker-desktop
```
### Run the tests
Most IDEs let you run individual tests or test fixtures directly from the code file. To run from the command line:
```bash
cd /path/to/logos-storage-nim-cs-dist-tests
# Run all release tests
dotnet test Tests/LogosStorageReleaseTests
# Run a specific test by name
dotnet test Tests/LogosStorageReleaseTests --filter=OneClientTest
# Run with verbose output
dotnet test Tests/LogosStorageReleaseTests --logger="console;verbosity=detailed"
```
### Useful environment variables
| Variable | Default | Description |
|---|---|---|
| `STORAGEDOCKERIMAGE` | `logosstorage/logos-storage-nim:latest-dist-tests` | Storage node image to test |
| `KUBECONFIG` | `~/.kube/config` | Path to kubeconfig file (optional when using Docker Desktop) |
| `LOGPATH` | `LogosStorageTestLogs` (relative) | Directory for test logs |
| `DATAFILEPATH` | `TestDataFiles` (relative) | Directory for test data files |
| `ALWAYS_LOGS` | _(unset)_ | Set to any non-empty value to always download container logs (not just on failure) |
| `TEST_TYPE` | _(unset)_ | Set to `release-tests` only when running inside the cluster (see §2c). Do **not** set this for local runs — it activates long in-cluster timeouts. |
Example — run against a specific Storage image:
```bash
STORAGEDOCKERIMAGE=logosstorage/logos-storage-nim:v0.1.8 dotnet test Tests/LogosStorageReleaseTests
```
### Troubleshooting
**`NullReferenceException` at `DistTest..ctor()`**
If every test fails immediately with a stack trace ending at `DistTest.GetWebCallTimeSet()` or `DistTest.GetK8sTimeSet()`, check whether `TEST_TYPE` is set to `release-tests` in your shell:
```bash
echo $TEST_TYPE
```
If it is, unset it before running locally:
```bash
unset TEST_TYPE
dotnet test Tests/LogosStorageReleaseTests
```
Setting `TEST_TYPE=release-tests` triggers in-cluster detection which tries to log a message through an object that hasn't been constructed yet, causing the crash.
**Tests fail with `kubectl` errors / wrong cluster**
Ensure the active context is `docker-desktop`, not a remote cluster:
On a remote cluster the test runner itself must run **inside** the cluster, because the framework needs direct pod-to-pod networking. The CI workflow does this automatically by creating a Kubernetes Job that runs the test runner image. You can also do it manually.
The test runner pod itself needs a kubeconfig to manage pods inside the cluster. Use a static service-account-based kubeconfig — avoid copying your local `~/.kube/config` directly, as it uses `gcloud` exec credentials that won't be available inside the pod.
| `RELEASE_TESTS_GCP_PROJECT` | GCP project ID — stored as a variable (not a secret) so it appears unmasked in logs and in the Cloud Logging link printed during the run |