Files
scadalink-design/docs/test_infra/test_infra.md

145 lines
6.0 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)
**Primary/backup testing**: The dual OPC UA test servers (ports 50000 and 50010) in local Docker and the dual LmxProxy v2 instances on windev (ports 50100 and 50101) provide primary/backup endpoint pairs for testing Data Connection Layer failover. Use `docker compose stop opcua` to simulate primary failure and verify automatic failover to the backup.
## 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)
```