001-reference-board-viewer #1
136
flake.nix
136
flake.nix
@@ -6,37 +6,41 @@
|
|||||||
flake-utils.url = "github:numtide/flake-utils";
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, flake-utils }:
|
outputs =
|
||||||
flake-utils.lib.eachDefaultSystem (system:
|
{ self, nixpkgs, flake-utils }:
|
||||||
|
flake-utils.lib.eachDefaultSystem (
|
||||||
|
system:
|
||||||
let
|
let
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
|
||||||
pythonEnv = pkgs.python3.withPackages (ps: with ps; [
|
pythonEnv = pkgs.python3.withPackages (
|
||||||
# Core backend dependencies
|
ps: with ps; [
|
||||||
fastapi
|
# Core backend dependencies
|
||||||
uvicorn
|
fastapi
|
||||||
sqlalchemy
|
uvicorn
|
||||||
alembic
|
sqlalchemy
|
||||||
pydantic
|
alembic
|
||||||
pydantic-settings # Settings management
|
pydantic
|
||||||
psycopg2 # PostgreSQL driver
|
pydantic-settings # Settings management
|
||||||
# Auth & Security
|
psycopg2 # PostgreSQL driver
|
||||||
python-jose
|
# Auth & Security
|
||||||
passlib
|
python-jose
|
||||||
bcrypt # Password hashing backend for passlib
|
passlib
|
||||||
email-validator # Email validation for pydantic
|
bcrypt # Password hashing backend for passlib
|
||||||
# Image processing
|
email-validator # Email validation for pydantic
|
||||||
pillow
|
# Image processing
|
||||||
# Storage
|
pillow
|
||||||
boto3
|
# Storage
|
||||||
# HTTP & uploads
|
boto3
|
||||||
httpx
|
# HTTP & uploads
|
||||||
python-multipart
|
httpx
|
||||||
# Testing
|
python-multipart
|
||||||
pytest
|
# Testing
|
||||||
pytest-cov
|
pytest
|
||||||
pytest-asyncio
|
pytest-cov
|
||||||
]);
|
pytest-asyncio
|
||||||
|
]
|
||||||
|
);
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
devShells.default = pkgs.mkShell {
|
devShells.default = pkgs.mkShell {
|
||||||
@@ -45,25 +49,25 @@
|
|||||||
pythonEnv
|
pythonEnv
|
||||||
uv
|
uv
|
||||||
ruff
|
ruff
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
postgresql
|
postgresql
|
||||||
|
|
||||||
# Frontend
|
# Frontend
|
||||||
nodejs
|
nodejs
|
||||||
nodePackages.npm
|
nodePackages.npm
|
||||||
|
|
||||||
# Image processing
|
# Image processing
|
||||||
imagemagick
|
imagemagick
|
||||||
|
|
||||||
# Storage
|
# Storage
|
||||||
minio
|
minio
|
||||||
minio-client
|
minio-client
|
||||||
|
|
||||||
# Development tools
|
# Development tools
|
||||||
git
|
git
|
||||||
direnv
|
direnv
|
||||||
|
|
||||||
# Optional: monitoring/debugging
|
# Optional: monitoring/debugging
|
||||||
# redis
|
# redis
|
||||||
];
|
];
|
||||||
@@ -89,7 +93,7 @@
|
|||||||
echo " App: http://localhost:5173"
|
echo " App: http://localhost:5173"
|
||||||
echo " MinIO UI: http://localhost:9001"
|
echo " MinIO UI: http://localhost:9001"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Set up environment variables
|
# Set up environment variables
|
||||||
export DATABASE_URL="postgresql://localhost/webref"
|
export DATABASE_URL="postgresql://localhost/webref"
|
||||||
export PYTHONPATH="$PWD/backend:$PYTHONPATH"
|
export PYTHONPATH="$PWD/backend:$PYTHONPATH"
|
||||||
@@ -98,12 +102,24 @@
|
|||||||
|
|
||||||
# Apps - Scripts that can be run with `nix run`
|
# Apps - Scripts that can be run with `nix run`
|
||||||
apps = {
|
apps = {
|
||||||
|
default = {
|
||||||
|
type = "app";
|
||||||
|
program = "${pkgs.writeShellScript "help" ''
|
||||||
|
echo "Available commands:"
|
||||||
|
echo " nix run .#lint - Run linting checks"
|
||||||
|
echo " nix run .#lint-fix - Auto-fix linting issues"
|
||||||
|
''}";
|
||||||
|
meta = {
|
||||||
|
description = "Show available commands";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# Unified linting for all code
|
# Unified linting for all code
|
||||||
lint = {
|
lint = {
|
||||||
type = "app";
|
type = "app";
|
||||||
program = "${pkgs.writeShellScript "lint" ''
|
program = "${pkgs.writeShellScript "lint" ''
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# Backend Python linting
|
# Backend Python linting
|
||||||
echo "🔍 Linting backend Python code..."
|
echo "🔍 Linting backend Python code..."
|
||||||
if [ -d "backend" ]; then
|
if [ -d "backend" ]; then
|
||||||
@@ -115,7 +131,7 @@
|
|||||||
echo "⚠ Not in project root (backend/ not found)"
|
echo "⚠ Not in project root (backend/ not found)"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Frontend linting (if node_modules exists)
|
# Frontend linting (if node_modules exists)
|
||||||
if [ -d "frontend/node_modules" ]; then
|
if [ -d "frontend/node_modules" ]; then
|
||||||
echo ""
|
echo ""
|
||||||
@@ -128,18 +144,21 @@
|
|||||||
else
|
else
|
||||||
echo "⚠ Frontend node_modules not found, run 'npm install' first"
|
echo "⚠ Frontend node_modules not found, run 'npm install' first"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "✅ All linting checks passed!"
|
echo "✅ All linting checks passed!"
|
||||||
''}";
|
''}";
|
||||||
|
meta = {
|
||||||
|
description = "Run linting checks on backend and frontend code";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Auto-fix linting issues
|
# Auto-fix linting issues
|
||||||
lint-fix = {
|
lint-fix = {
|
||||||
type = "app";
|
type = "app";
|
||||||
program = "${pkgs.writeShellScript "lint-fix" ''
|
program = "${pkgs.writeShellScript "lint-fix" ''
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
echo "🔧 Auto-fixing backend Python code..."
|
echo "🔧 Auto-fixing backend Python code..."
|
||||||
if [ -d "backend" ]; then
|
if [ -d "backend" ]; then
|
||||||
cd backend
|
cd backend
|
||||||
@@ -150,7 +169,7 @@
|
|||||||
echo "⚠ Not in project root (backend/ not found)"
|
echo "⚠ Not in project root (backend/ not found)"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -d "frontend/node_modules" ]; then
|
if [ -d "frontend/node_modules" ]; then
|
||||||
echo ""
|
echo ""
|
||||||
echo "🔧 Auto-fixing frontend code..."
|
echo "🔧 Auto-fixing frontend code..."
|
||||||
@@ -158,33 +177,52 @@
|
|||||||
${pkgs.nodePackages.prettier}/bin/prettier --write src/
|
${pkgs.nodePackages.prettier}/bin/prettier --write src/
|
||||||
cd ..
|
cd ..
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "✅ Auto-fix complete!"
|
echo "✅ Auto-fix complete!"
|
||||||
''}";
|
''}";
|
||||||
|
meta = {
|
||||||
|
description = "Auto-fix linting issues in backend and frontend code";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Package definitions (for production deployment)
|
# Package definitions (for production deployment)
|
||||||
packages = {
|
packages = rec {
|
||||||
# Backend package
|
# Backend package
|
||||||
backend = pkgs.python3Packages.buildPythonApplication {
|
backend = pkgs.python3Packages.buildPythonApplication {
|
||||||
pname = "webref-backend";
|
pname = "webref-backend";
|
||||||
version = "1.0.0";
|
version = "1.0.0";
|
||||||
|
pyproject = true;
|
||||||
src = ./backend;
|
src = ./backend;
|
||||||
|
|
||||||
|
build-system = with pkgs.python3Packages; [
|
||||||
|
setuptools
|
||||||
|
];
|
||||||
|
|
||||||
propagatedBuildInputs = with pkgs.python3Packages; [
|
propagatedBuildInputs = with pkgs.python3Packages; [
|
||||||
fastapi
|
fastapi
|
||||||
uvicorn
|
uvicorn
|
||||||
sqlalchemy
|
sqlalchemy
|
||||||
alembic
|
alembic
|
||||||
pydantic
|
pydantic
|
||||||
|
pydantic-settings
|
||||||
|
psycopg2
|
||||||
python-jose
|
python-jose
|
||||||
passlib
|
passlib
|
||||||
pillow
|
pillow
|
||||||
boto3
|
boto3
|
||||||
httpx
|
httpx
|
||||||
python-multipart
|
python-multipart
|
||||||
|
email-validator
|
||||||
|
bcrypt
|
||||||
];
|
];
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "Reference Board Viewer - Backend API";
|
||||||
|
homepage = "https://github.com/yourusername/webref";
|
||||||
|
license = pkgs.lib.licenses.mit;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Frontend package
|
# Frontend package
|
||||||
@@ -192,7 +230,7 @@
|
|||||||
pname = "webref-frontend";
|
pname = "webref-frontend";
|
||||||
version = "1.0.0";
|
version = "1.0.0";
|
||||||
src = ./frontend;
|
src = ./frontend;
|
||||||
npmDepsHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; # Update after first build
|
npmDepsHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; # Update after first build
|
||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
npm run build
|
npm run build
|
||||||
'';
|
'';
|
||||||
@@ -200,7 +238,14 @@
|
|||||||
mkdir -p $out
|
mkdir -p $out
|
||||||
cp -r build/* $out/
|
cp -r build/* $out/
|
||||||
'';
|
'';
|
||||||
|
meta = {
|
||||||
|
description = "Reference Board Viewer - Frontend SPA";
|
||||||
|
homepage = "https://github.com/yourusername/webref";
|
||||||
|
license = pkgs.lib.licenses.mit;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
default = backend;
|
||||||
};
|
};
|
||||||
|
|
||||||
# NixOS VM tests
|
# NixOS VM tests
|
||||||
@@ -208,4 +253,3 @@
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
{ config, pkgs, lib, ... }:
|
{ pkgs, ... }:
|
||||||
|
|
||||||
{
|
{
|
||||||
# Gitea Actions Runner Configuration
|
# Gitea Actions Runner Configuration
|
||||||
@@ -6,36 +6,36 @@
|
|||||||
|
|
||||||
services.gitea-actions-runner = {
|
services.gitea-actions-runner = {
|
||||||
package = pkgs.gitea-actions-runner;
|
package = pkgs.gitea-actions-runner;
|
||||||
|
|
||||||
instances = {
|
instances = {
|
||||||
# Main runner instance for webref project
|
# Main runner instance for webref project
|
||||||
webref-runner = {
|
webref-runner = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
# Runner name (will appear in Gitea)
|
# Runner name (will appear in Gitea)
|
||||||
name = "nixos-runner-webref";
|
name = "nixos-runner-webref";
|
||||||
|
|
||||||
# Gitea instance URL
|
# Gitea instance URL
|
||||||
url = "https://your-gitea-instance.com";
|
url = "https://your-gitea-instance.com";
|
||||||
|
|
||||||
# Runner token - Generate this from Gitea:
|
# Runner token - Generate this from Gitea:
|
||||||
# Settings -> Actions -> Runners -> Create New Runner
|
# Settings -> Actions -> Runners -> Create New Runner
|
||||||
# Store the token in a file and reference it here
|
# Store the token in a file and reference it here
|
||||||
tokenFile = "/var/secrets/gitea-runner-token";
|
tokenFile = "/var/secrets/gitea-runner-token";
|
||||||
|
|
||||||
# Labels define what jobs this runner can handle
|
# Labels define what jobs this runner can handle
|
||||||
# Format: "label:docker_image" or just "label" for host execution
|
# Format: "label:docker_image" or just "label" for host execution
|
||||||
labels = [
|
labels = [
|
||||||
# Native execution with Nix
|
# Native execution with Nix
|
||||||
"nix:native"
|
"nix:native"
|
||||||
|
|
||||||
# Ubuntu-like for compatibility
|
# Ubuntu-like for compatibility
|
||||||
"ubuntu-latest:docker://node:20-bookworm"
|
"ubuntu-latest:docker://node:20-bookworm"
|
||||||
|
|
||||||
# Specific for this project
|
# Specific for this project
|
||||||
"webref:native"
|
"webref:native"
|
||||||
];
|
];
|
||||||
|
|
||||||
# Host packages available to the runner
|
# Host packages available to the runner
|
||||||
hostPackages = with pkgs; [
|
hostPackages = with pkgs; [
|
||||||
# Essential tools
|
# Essential tools
|
||||||
@@ -44,15 +44,15 @@
|
|||||||
curl
|
curl
|
||||||
git
|
git
|
||||||
nix
|
nix
|
||||||
|
|
||||||
# Project-specific
|
# Project-specific
|
||||||
nodejs
|
nodejs
|
||||||
python3
|
python3
|
||||||
postgresql
|
postgresql
|
||||||
|
|
||||||
# Binary cache
|
# Binary cache
|
||||||
attic-client
|
attic-client
|
||||||
|
|
||||||
# Container runtime (optional)
|
# Container runtime (optional)
|
||||||
docker
|
docker
|
||||||
docker-compose
|
docker-compose
|
||||||
@@ -75,16 +75,19 @@
|
|||||||
extraGroups = [ "docker" ];
|
extraGroups = [ "docker" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
users.groups.gitea-runner = {};
|
users.groups.gitea-runner = { };
|
||||||
|
|
||||||
# Allow runner to use Nix
|
# Allow runner to use Nix
|
||||||
nix.settings = {
|
nix.settings = {
|
||||||
allowed-users = [ "gitea-runner" ];
|
allowed-users = [ "gitea-runner" ];
|
||||||
trusted-users = [ "gitea-runner" ];
|
trusted-users = [ "gitea-runner" ];
|
||||||
|
|
||||||
# Enable flakes for the runner
|
# Enable flakes for the runner
|
||||||
experimental-features = [ "nix-command" "flakes" ];
|
experimental-features = [
|
||||||
|
"nix-command"
|
||||||
|
"flakes"
|
||||||
|
];
|
||||||
|
|
||||||
# Optimize for CI performance
|
# Optimize for CI performance
|
||||||
max-jobs = "auto";
|
max-jobs = "auto";
|
||||||
cores = 0; # Use all available cores
|
cores = 0; # Use all available cores
|
||||||
@@ -102,11 +105,10 @@
|
|||||||
# Resource limits (adjust based on your hardware)
|
# Resource limits (adjust based on your hardware)
|
||||||
MemoryMax = "8G";
|
MemoryMax = "8G";
|
||||||
CPUQuota = "400%"; # 4 cores
|
CPUQuota = "400%"; # 4 cores
|
||||||
|
|
||||||
# Restart policy
|
# Restart policy
|
||||||
Restart = "always";
|
Restart = "always";
|
||||||
RestartSec = "10s";
|
RestartSec = "10s";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
248
nixos/tests.nix
248
nixos/tests.nix
@@ -4,189 +4,203 @@
|
|||||||
# Backend integration tests with PostgreSQL and MinIO
|
# Backend integration tests with PostgreSQL and MinIO
|
||||||
backend-integration = pkgs.testers.nixosTest {
|
backend-integration = pkgs.testers.nixosTest {
|
||||||
name = "webref-backend-integration";
|
name = "webref-backend-integration";
|
||||||
|
|
||||||
nodes = {
|
nodes = {
|
||||||
machine = { config, pkgs, ... }: {
|
machine =
|
||||||
# PostgreSQL service
|
{ pkgs, ... }:
|
||||||
services.postgresql = {
|
{
|
||||||
enable = true;
|
# PostgreSQL service
|
||||||
ensureDatabases = [ "webref" ];
|
services.postgresql = {
|
||||||
ensureUsers = [{
|
enable = true;
|
||||||
name = "webref";
|
ensureDatabases = [ "webref" ];
|
||||||
ensureDBOwnership = true;
|
ensureUsers = [
|
||||||
}];
|
{
|
||||||
authentication = ''
|
name = "webref";
|
||||||
local all all trust
|
ensureDBOwnership = true;
|
||||||
host all all 127.0.0.1/32 trust
|
}
|
||||||
host all all ::1/128 trust
|
];
|
||||||
'';
|
authentication = ''
|
||||||
|
local all all trust
|
||||||
|
host all all 127.0.0.1/32 trust
|
||||||
|
host all all ::1/128 trust
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# MinIO service
|
||||||
|
services.minio = {
|
||||||
|
enable = true;
|
||||||
|
rootCredentialsFile = pkgs.writeText "minio-credentials" ''
|
||||||
|
MINIO_ROOT_USER=minioadmin
|
||||||
|
MINIO_ROOT_PASSWORD=minioadmin
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# Install required packages
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
python3
|
||||||
|
python3Packages.pytest
|
||||||
|
python3Packages.fastapi
|
||||||
|
postgresql
|
||||||
|
curl
|
||||||
|
];
|
||||||
|
|
||||||
|
# Network configuration
|
||||||
|
networking.firewall.enable = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
# MinIO service
|
|
||||||
services.minio = {
|
|
||||||
enable = true;
|
|
||||||
rootCredentialsFile = pkgs.writeText "minio-credentials" ''
|
|
||||||
MINIO_ROOT_USER=minioadmin
|
|
||||||
MINIO_ROOT_PASSWORD=minioadmin
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
# Install required packages
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
python3
|
|
||||||
python3Packages.pytest
|
|
||||||
python3Packages.fastapi
|
|
||||||
postgresql
|
|
||||||
curl
|
|
||||||
];
|
|
||||||
|
|
||||||
# Network configuration
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
start_all()
|
start_all()
|
||||||
|
|
||||||
# Wait for PostgreSQL
|
# Wait for PostgreSQL
|
||||||
machine.wait_for_unit("postgresql.service")
|
machine.wait_for_unit("postgresql.service")
|
||||||
machine.wait_for_open_port(5432)
|
machine.wait_for_open_port(5432)
|
||||||
|
|
||||||
# Wait for MinIO
|
# Wait for MinIO
|
||||||
machine.wait_for_unit("minio.service")
|
machine.wait_for_unit("minio.service")
|
||||||
machine.wait_for_open_port(9000)
|
machine.wait_for_open_port(9000)
|
||||||
|
|
||||||
# Verify PostgreSQL is working
|
# Verify PostgreSQL is working
|
||||||
machine.succeed("sudo -u postgres psql -c 'SELECT 1;'")
|
machine.succeed("sudo -u postgres psql -c 'SELECT 1;'")
|
||||||
|
|
||||||
# Verify MinIO is working
|
# Verify MinIO is working
|
||||||
machine.succeed("curl -f http://localhost:9000/minio/health/live")
|
machine.succeed("curl -f http://localhost:9000/minio/health/live")
|
||||||
|
|
||||||
machine.succeed("echo '✅ Backend integration test passed'")
|
machine.succeed("echo '✅ Backend integration test passed'")
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# Full stack test with backend + database
|
# Full stack test with backend + database
|
||||||
full-stack = pkgs.testers.nixosTest {
|
full-stack = pkgs.testers.nixosTest {
|
||||||
name = "webref-full-stack";
|
name = "webref-full-stack";
|
||||||
|
|
||||||
nodes = {
|
nodes = {
|
||||||
machine = { config, pkgs, ... }: {
|
machine =
|
||||||
# PostgreSQL
|
{ pkgs, ... }:
|
||||||
services.postgresql = {
|
{
|
||||||
enable = true;
|
# PostgreSQL
|
||||||
ensureDatabases = [ "webref" ];
|
services.postgresql = {
|
||||||
ensureUsers = [{
|
enable = true;
|
||||||
name = "webref";
|
ensureDatabases = [ "webref" ];
|
||||||
ensureDBOwnership = true;
|
ensureUsers = [
|
||||||
}];
|
{
|
||||||
|
name = "webref";
|
||||||
|
ensureDBOwnership = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# MinIO
|
||||||
|
services.minio = {
|
||||||
|
enable = true;
|
||||||
|
rootCredentialsFile = pkgs.writeText "minio-credentials" ''
|
||||||
|
MINIO_ROOT_USER=minioadmin
|
||||||
|
MINIO_ROOT_PASSWORD=minioadmin
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
python3
|
||||||
|
curl
|
||||||
|
jq
|
||||||
|
];
|
||||||
|
|
||||||
|
networking.firewall.enable = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
# MinIO
|
|
||||||
services.minio = {
|
|
||||||
enable = true;
|
|
||||||
rootCredentialsFile = pkgs.writeText "minio-credentials" ''
|
|
||||||
MINIO_ROOT_USER=minioadmin
|
|
||||||
MINIO_ROOT_PASSWORD=minioadmin
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
python3
|
|
||||||
curl
|
|
||||||
jq
|
|
||||||
];
|
|
||||||
|
|
||||||
networking.firewall.enable = false;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
start_all()
|
start_all()
|
||||||
|
|
||||||
# Wait for services
|
# Wait for services
|
||||||
machine.wait_for_unit("postgresql.service")
|
machine.wait_for_unit("postgresql.service")
|
||||||
machine.wait_for_unit("minio.service")
|
machine.wait_for_unit("minio.service")
|
||||||
machine.wait_for_open_port(5432)
|
machine.wait_for_open_port(5432)
|
||||||
machine.wait_for_open_port(9000)
|
machine.wait_for_open_port(9000)
|
||||||
|
|
||||||
# Test database connectivity
|
# Test database connectivity
|
||||||
machine.succeed("sudo -u postgres psql -c 'SELECT version();'")
|
machine.succeed("sudo -u postgres psql -c 'SELECT version();'")
|
||||||
|
|
||||||
# Test MinIO API
|
# Test MinIO API
|
||||||
machine.succeed("curl -f http://localhost:9000/minio/health/live")
|
machine.succeed("curl -f http://localhost:9000/minio/health/live")
|
||||||
|
|
||||||
machine.succeed("echo '✅ Full stack test passed'")
|
machine.succeed("echo '✅ Full stack test passed'")
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# Performance benchmarks
|
# Performance benchmarks
|
||||||
performance = pkgs.testers.nixosTest {
|
performance = pkgs.testers.nixosTest {
|
||||||
name = "webref-performance";
|
name = "webref-performance";
|
||||||
|
|
||||||
nodes = {
|
nodes = {
|
||||||
machine = { config, pkgs, ... }: {
|
machine =
|
||||||
services.postgresql.enable = true;
|
{ pkgs, ... }:
|
||||||
services.minio.enable = true;
|
{
|
||||||
|
services.postgresql.enable = true;
|
||||||
environment.systemPackages = with pkgs; [
|
services.minio.enable = true;
|
||||||
python3
|
|
||||||
];
|
environment.systemPackages = with pkgs; [
|
||||||
};
|
python3
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
start_all()
|
start_all()
|
||||||
machine.wait_for_unit("postgresql.service")
|
machine.wait_for_unit("postgresql.service")
|
||||||
|
|
||||||
machine.succeed("echo '✅ Performance test passed'")
|
machine.succeed("echo '✅ Performance test passed'")
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# Security tests
|
# Security tests
|
||||||
security = pkgs.testers.nixosTest {
|
security = pkgs.testers.nixosTest {
|
||||||
name = "webref-security";
|
name = "webref-security";
|
||||||
|
|
||||||
nodes = {
|
nodes = {
|
||||||
machine = { config, pkgs, ... }: {
|
machine =
|
||||||
services.postgresql = {
|
{ pkgs, ... }:
|
||||||
enable = true;
|
{
|
||||||
ensureDatabases = [ "webref" ];
|
services.postgresql = {
|
||||||
ensureUsers = [{
|
enable = true;
|
||||||
name = "webref";
|
ensureDatabases = [ "webref" ];
|
||||||
ensureDBOwnership = true;
|
ensureUsers = [
|
||||||
}];
|
{
|
||||||
|
name = "webref";
|
||||||
|
ensureDBOwnership = true;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Create system user for testing
|
||||||
|
users.users.webref = {
|
||||||
|
isSystemUser = true;
|
||||||
|
group = "webref";
|
||||||
|
};
|
||||||
|
users.groups.webref = { };
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
python3
|
||||||
|
nmap
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
# Create system user for testing
|
|
||||||
users.users.webref = {
|
|
||||||
isSystemUser = true;
|
|
||||||
group = "webref";
|
|
||||||
};
|
|
||||||
users.groups.webref = {};
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
python3
|
|
||||||
nmap
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
testScript = ''
|
testScript = ''
|
||||||
start_all()
|
start_all()
|
||||||
machine.wait_for_unit("postgresql.service")
|
machine.wait_for_unit("postgresql.service")
|
||||||
|
|
||||||
# Wait for PostgreSQL setup scripts to complete (database and user creation)
|
# Wait for PostgreSQL setup scripts to complete (database and user creation)
|
||||||
import time
|
import time
|
||||||
machine.wait_for_unit("postgresql-setup.service", timeout=30)
|
machine.wait_for_unit("postgresql-setup.service", timeout=30)
|
||||||
time.sleep(2) # Give it a moment to finalize
|
time.sleep(2) # Give it a moment to finalize
|
||||||
|
|
||||||
# Verify database role exists
|
# Verify database role exists
|
||||||
machine.succeed("sudo -u postgres psql -c '\\du' | grep webref")
|
machine.succeed("sudo -u postgres psql -c '\\du' | grep webref")
|
||||||
|
|
||||||
# Verify database is accessible with webref user
|
# Verify database is accessible with webref user
|
||||||
machine.succeed("sudo -u webref psql webref -c 'SELECT 1;'")
|
machine.succeed("sudo -u webref psql webref -c 'SELECT 1;'")
|
||||||
|
|
||||||
machine.succeed("echo '✅ Security test passed'")
|
machine.succeed("echo '✅ Security test passed'")
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user