Files
scadalink-design/docs/test_infra/test_infra.md
Joseph Doherty abb7579227 chore(infra): remove LmxFakeProxy — replaced by real LmxProxy v2 instances on windev
LmxFakeProxy is no longer needed now that two real LmxProxy v2 instances
are available for testing. Added remote test infra section to test_infra.md
documenting the windev instances. Removed tagsim (never committed).
2026-03-22 07:42:13 -04:00

143 lines
5.7 KiB
Markdown

# Test Infrastructure
This document describes the local Docker-based test infrastructure for ScadaLink development. Seven services provide the external dependencies needed to run and test the system locally. The first seven run in `infra/docker-compose.yml`; Traefik runs alongside the cluster nodes in `docker/docker-compose.yml`.
## Services
| Service | Image | Port(s) | Config | Compose File |
|---------|-------|---------|--------|-------------|
| OPC UA Server | `mcr.microsoft.com/iotedge/opc-plc:latest` | 50000 (OPC UA), 8080 (web) | `infra/opcua/nodes.json` | `infra/` |
| OPC UA Server 2 | `mcr.microsoft.com/iotedge/opc-plc:latest` | 50010 (OPC UA), 8081 (web) | `infra/opcua/nodes.json` | `infra/` |
| LDAP Server | `glauth/glauth:latest` | 3893 | `infra/glauth/config.toml` | `infra/` |
| MS SQL 2022 | `mcr.microsoft.com/mssql/server:2022-latest` | 1433 | `infra/mssql/setup.sql` | `infra/` |
| SMTP (Mailpit) | `axllent/mailpit:latest` | 1025 (SMTP), 8025 (web) | Environment vars | `infra/` |
| REST API (Flask) | Custom build (`infra/restapi/Dockerfile`) | 5200 | `infra/restapi/app.py` | `infra/` |
| Playwright | `mcr.microsoft.com/playwright:v1.58.2-noble` | 3000 (WebSocket) | Command args | `infra/` |
| Traefik LB | `traefik:v3.4` | 9000 (proxy), 8180 (dashboard) | `docker/traefik/` | `docker/` |
## Quick Start
```bash
cd infra
docker compose up -d
```
After the first startup, run the SQL setup and seed scripts:
```bash
docker exec -i scadalink-mssql /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P 'ScadaLink_Dev1#' -C \
-i /docker-entrypoint-initdb.d/setup.sql
docker exec -i scadalink-mssql /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P 'ScadaLink_Dev1#' -C \
-i /docker-entrypoint-initdb.d/machinedata_seed.sql
```
## Per-Service Documentation
Each service has a dedicated document with configuration details, verification steps, and troubleshooting:
- [test_infra_opcua.md](test_infra_opcua.md) — OPC UA test server (Azure IoT OPC PLC)
- [test_infra_ldap.md](test_infra_ldap.md) — LDAP test server (GLAuth)
- [test_infra_db.md](test_infra_db.md) — MS SQL 2022 database
- [test_infra_smtp.md](test_infra_smtp.md) — SMTP test server (Mailpit)
- [test_infra_restapi.md](test_infra_restapi.md) — REST API test server (Flask)
- [test_infra_playwright.md](test_infra_playwright.md) — Playwright browser server (Central UI testing)
- Traefik LB — see `docker/README.md` and `docker/traefik/` (runs with the cluster, not in `infra/`)
## Remote Test Infrastructure
In addition to the local Docker services, the following remote services are available for testing against real AVEVA System Platform hardware.
### LmxProxy v2 (windev — 10.100.0.48)
Two LmxProxy v2 instances run as Windows services on windev, both connected to the same AVEVA System Platform via MxAccess COM. These provide the primary/backup pair for Data Connection Layer testing.
| | Instance A | Instance B |
|---|---|---|
| **gRPC Endpoint** | `10.100.0.48:50100` | `10.100.0.48:50101` |
| **HTTP Status** | `http://10.100.0.48:8081` | `http://10.100.0.48:8082` |
| **Service Name** | `ZB.MOM.WW.LmxProxy.Host.V2` | `ZB.MOM.WW.LmxProxy.Host.V2B` |
API key (ReadWrite): `c4559c7c6acc60a997135c1381162e3c30f4572ece78dd933c1a626e6fd933b4`
Full details: [`lmxproxy/instances_config.md`](../../lmxproxy/instances_config.md)
## Connection Strings
For use in `appsettings.Development.json`:
```json
{
"ConnectionStrings": {
"ScadaLinkConfig": "Server=localhost,1433;Database=ScadaLinkConfig;User Id=scadalink_app;Password=ScadaLink_Dev1#;TrustServerCertificate=true",
"ScadaLinkMachineData": "Server=localhost,1433;Database=ScadaLinkMachineData;User Id=scadalink_app;Password=ScadaLink_Dev1#;TrustServerCertificate=true"
},
"Ldap": {
"Server": "localhost",
"Port": 3893,
"BaseDN": "dc=scadalink,dc=local",
"UseSsl": false
},
"OpcUa": {
"EndpointUrl": "opc.tcp://localhost:50000"
},
"OpcUa2": {
"EndpointUrl": "opc.tcp://localhost:50010"
},
"Smtp": {
"Server": "localhost",
"Port": 1025,
"AuthMode": "None",
"FromAddress": "scada-notifications@company.com",
"ConnectionTimeout": 30
},
"ExternalSystems": {
"TestApi": {
"BaseUrl": "http://localhost:5200",
"AuthMode": "ApiKey",
"ApiKey": "scadalink-test-key-1"
}
}
}
```
## Stopping & Teardown
```bash
cd infra
docker compose down # stop containers, preserve SQL data volume
docker compose stop opcua # stop a single service (also: opcua2, ldap, mssql, smtp, restapi)
```
**Full teardown** (removes volumes, optionally images and venv):
```bash
cd infra
./teardown.sh # stop containers + delete SQL data volume
./teardown.sh --images # also remove downloaded Docker images
./teardown.sh --all # also remove the Python venv
```
After a full teardown, the next `docker compose up -d` starts fresh — re-run the SQL setup script.
## Files
```
infra/
docker-compose.yml # All seven services
teardown.sh # Teardown script (volumes, images, venv)
glauth/config.toml # LDAP users and groups
mssql/setup.sql # Database and user creation
mssql/machinedata_seed.sql # Machine Data tables, stored procedures, sample data
opcua/nodes.json # Custom OPC UA tag definitions
restapi/app.py # Flask REST API server
restapi/Dockerfile # REST API container build
tools/ # Python CLI tools (opcua, ldap, mssql, smtp, restapi)
README.md # Quick-start for the infra folder
docker/
traefik/traefik.yml # Traefik static config (entrypoints, file provider)
traefik/dynamic.yml # Traefik dynamic config (load balancer, health check routing)
```