added test infrastructure based on docker/podman

* documentation added
* scripts to setup image and start container added
This commit is contained in:
2026-02-15 17:53:46 +01:00
parent 3c6856d68b
commit bc1e17ec04
9 changed files with 334 additions and 12 deletions
+168
View File
@@ -0,0 +1,168 @@
AGENTS
I created this `AGENTS.md` to help agentic coding assistants work in this repository. It contains
1) Build / lint / test commands (including how to run a single test) and
2) Code style guidelines and conventions to follow when editing code here.
Repository state
- This repository contains shell scripts for Linux Mint XFCE post-installation setup.
- Main scripts are located in `post_installation_script/` directory.
- Testing infrastructure is in `post_installation_script_test/` (Docker/Podman test containers).
- No build system, package.json, Makefile, or language-specific project files were detected.
- There are no Cursor rules or Copilot instruction files in the repo (checked paths below).
- `.cursor/rules/` : not found
- `.cursorrules` : not found
- `.github/copilot-instructions.md` : not found
If you add new code (Go, Python, Node, Rust, Java, etc.), follow the per-ecosystem quick commands below.
1) Build / Lint / Test commands
- General notes
- Run commands from the repository root unless a submodule or service has its own README.
- Prefer local, repo-scoped toolchains (venv, node_modules/.bin, go modules, cargo) to avoid global state.
- Shell scripts
- Quick check: `shellcheck scripts/*.sh` (install `shellcheck` first).
- Run an individual script: `bash path/to/script.sh` or `./script.sh` (ensure executable bit set).
- Syntax check: `bash -n path/to/script.sh`
- Trace execution: `bash -x path/to/script.sh` (shows each command as it runs)
- Testing shell scripts
- See `post_installation_script_test/README.md` for detailed container-based testing instructions.
- Quick start:
- Build image: `./post_installation_script_test/01_create_image.sh`
- Start container: `./post_installation_script_test/02_start_container_with_image.sh`
- Python (if added)
- Install: `python -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt`
- Lint: `ruff .` or `flake8 .`
- Format: `black .`
- Test all: `pytest -q`
- Run a single test: `pytest path/to/test_file.py::TestClass::test_method -q`
- Node / JavaScript / TypeScript (if added)
- Install: `npm ci` or `pnpm install` / `yarn install`
- Lint: `npm run lint` (or `npx eslint .`)
- Format: `npx prettier --write .`
- Test all: `npm test` (or `npx vitest` / `npx jest`)
- Run a single test:
- Jest: `npx jest path/to/file.test.js -t "test name regex"`
- Vitest: `npx vitest run path/to/file.spec.ts -t "test name"`
- Go (if added)
- Build: `go build ./...`
- Lint: `golangci-lint run` (if configured)
- Test all: `go test ./...`
- Run a single test: `go test ./pkg/name -run TestFunctionName`
- Rust (if added)
- Build: `cargo build`
- Lint: `cargo clippy`
- Test all: `cargo test`
- Run a single test: `cargo test test_name -- --exact`
- Java / Maven (if added)
- Build: `mvn -DskipTests package`
- Lint/format: use `spotless`/`checkstyle` if configured
- Test all: `mvn test`
- Run a single test: `mvn -Dtest=ClassName#methodName test`
- .NET (if added)
- Build: `dotnet build`
- Test all: `dotnet test`
- Run a single test: `dotnet test --filter FullyQualifiedName~Namespace.ClassName.MethodName`
- CI / Automation
- If you add GitHub Actions, keep workflows idempotent and cache dependencies carefully.
- Avoid secrets in workflows; read sensitive values from repository/organization secrets.
2) Code style guidelines
The guidance below is intentionally general and focuses on consistency, readability and safety so
agentic tools can make changes predictably across multiple languages.
- Formatting
- Use an automated formatter for the language (Black for Python, Prettier for JS/TS, gofmt/gofmt -s for Go,
rustfmt for Rust). Commit formatted code only.
- Use an editorconfig file for basic whitespace/indentation rules when possible.
- Imports / dependencies
- Keep imports explicit and minimal: import only what you use.
- Group imports in a logical order (language default + third-party + local project). Leave a blank line between groups.
- Dont commit unused dependencies; remove them from lock files / manifests and run the linter.
- Types / typing
- Prefer explicit types where the language supports them (TypeScript types, Python type hints, Go static types).
- Add types for public interfaces and complex logic; internal simple helper functions may rely on inference.
- Naming conventions
- Use clear, descriptive names. Prefer `calculate_total`, `prepare_connection`, `user_id` style for snake_case languages.
- For camelCase languages (JS/TS): `calculateTotal`, `prepareConnection`.
- Types and classes: use PascalCase/UpperCamelCase: `UserService`, `HttpClient`.
- Constants: use UPPER_SNAKE_CASE or language-specific constant conventions.
- Functions and modules
- Keep functions small (ideally < 40 lines) and single-responsibility.
- Prefer pure functions where possible; keep side effects explicit and isolated.
- Organize modules by feature/domain, not solely by type (avoid monolithic god-modules).
- Error handling
- Fail fast and return/raise errors with context (message + cause) rather than swallowing them.
- Avoid logging raw errors in library code; return errors to callers and let the application layer decide logging.
- Use typed error types when the language supports it (Go error types, custom exceptions in Python/JS).
- Clean up resources with `finally`/`defer` equivalents to avoid leaks.
- Tests
- Prefer small, deterministic unit tests. Mock external IO and network where reasonable.
- Use explicit fixtures and avoid implicit global state between tests.
- Name tests with the behavior they assert: `test_calculate_total_with_discounts` or `shouldReturn400WhenMissingField`.
- Logging and observability
- Use structured logging where available (JSON structured logs for services).
- Avoid printing raw stack traces to stdout in production code; include them at debug level.
- Security and secrets
- Never commit secrets, API keys, or credentials. Use environment variables and vaults.
- Validate and sanitize external input at the boundaries of the system.
- Performance
- Measure before optimizing. Prefer clarity over micro-optimizations unless a hotspot is identified.
3) Code review / commit guidance for agents
- Make small, focused commits and include a one-line summary plus a short description of the why.
- When changing behavior, add or update tests that verify the new/changed behavior.
- If you reformat files automatically, include the formatter command in the commit message to make CI reproduction easy.
4) Repo housekeeping checks (recommended for agents)
- When adding a new language or framework, add an entry to this file with the exact commands required to build/test.
- Add CI workflows to run lint + tests on PRs and enable branch protection rules if this becomes a shared repo.
5) Cursor / Copilot rules
- Cursor rules: none present at `.cursor/rules/` or `.cursorrules` in this repository.
- GitHub Copilot instructions: none present at `.github/copilot-instructions.md`.
If you add any of these files, update this document and include the exact file path and relevant sections for agents to follow.
Quick checklist for an agent making changes
- Run local linter/formatter configured for the language before opening a PR.
- Run the test suite and the single-test command for any tests you added/changed.
- Do not add secrets to the tree; use placeholders and document required environment variables.
Next steps (recommended)
1) Add a minimal `Makefile` or `package.json` scripts for common tasks so agents can run `make test` / `npm test`.
2) If the project will contain multiple services, add per-service README files and CI workflows.
3) Add EditorConfig + language-specific formatter configs (pyproject.toml, .prettierrc, rustfmt.toml) to lock formatting rules.
Files referenced
- Root `README.md`
- `post_installation_script/README.md` - main script usage
- `post_installation_script_test/README.md` - testing instructions
- `.cursor/rules/` (not present)
- `.cursorrules` (not present)
- `.github/copilot-instructions.md` (not present)
If anything in this file needs to be stricter or you want another style (for example a fully opinionated TS style), say which language or style and I will update `AGENTS.md` accordingly.
+24
View File
@@ -0,0 +1,24 @@
# OS
.DS_Store
Thumbs.db
*~
# IDE
.idea/
*.swp
*.swo
*~
.vscode/
# Test containers
*.tar.gz
fonts-main/
*.log
# Temporary files
tmp/
temp/
*.tmp
# agent specific sessions
.agents/sessions/*
@@ -51,13 +51,13 @@ echo "
#
#
#
sudo apt-get update
sudo apt-get update
sSuffixDate=$(date '+%Y-%m-%d_%H:%M:%S')
echo
if question_answered_with_yes "#### 64 bit Mint XFCE ; Zusatzprogramme ####\nGeben Sie j oder n ein und die Eingabetaste,\nAbbruch mit jeder anderen Taste ..."; then
if question_answered_with_yes $'#### 64 bit Mint XFCE ; Zusatzprogramme ####\nGeben Sie j oder n ein und die Eingabetaste,\nAbbruch mit jeder anderen Taste ...'; then
echo "#### 64 bit Mint XFCE ####"
sudo apt -y install xfce4-goodies clementine vlc htop hardinfo font-manager asunder gtkhash xfce4-panel-profiles
bIsVlcInstalled=true
@@ -70,7 +70,7 @@ echo
echo "#### nur auf Wunsch / bei Bedarf ####"
echo
### Sensoren ###
if question_answered_with_yes " ### Sensoren ###\nGeben Sie j oder n ein und die Eingabetaste,\nAbbruch mit jeder anderen Taste ..."; then
if question_answered_with_yes $' ### Sensoren ###\nGeben Sie j oder n ein und die Eingabetaste,\nAbbruch mit jeder anderen Taste ...'; then
echo "### Sensoren ###"
sudo apt install lm-sensors psensor
sudo sensors-detect
@@ -83,7 +83,7 @@ echo
echo
if [ "$bIsVlcInstalled" = true ]; then
echo "### Kauf-DVDs abspielen ###"
if question_answered_with_yes " ### Film DVDs ###\n\tGeben Sie j oder n ein und die Eingabetaste,\n\tAbbruch mit jeder anderen Taste ..."; then
if question_answered_with_yes $' ### Film DVDs ###\n\tGeben Sie j oder n ein und die Eingabetaste,\n\tAbbruch mit jeder anderen Taste ...'; then
echo "### Kauf-DVDs abspielen ###"
sudo apt install libdvd-pkg
sudo dpkg-reconfigure libdvd-pkg
@@ -99,7 +99,7 @@ echo
echo "### Schriften, falls Microsoft-Office-Dokumente weiterverwendet werden sollen oder Dokumentenaustausch mit Microsoft-Nutzern gewünscht ist ###
## frei verfügbare, alte Microsoft-Standardschriften installieren:"
if question_answered_with_yes " ### M$ Schriften ###\nGeben Sie j oder n ein und die Eingabetaste,\nAbbruch mit jeder anderen Taste ..."; then
if question_answered_with_yes $' ### M$ Schriften ###\nGeben Sie j oder n ein und die Eingabetaste,\nAbbruch mit jeder anderen Taste ...'; then
echo "### M$ Schriften ###"
sudo apt install ttf-mscorefonts-installer
fi
@@ -107,7 +107,7 @@ fi
echo
echo
echo " ## freie Google-Schriften als Ersatz für aktuelle MS-Standardschriften installieren:"
if question_answered_with_yes " ### Google Schriften ###\nGeben Sie j oder n ein und die Eingabetaste,\nAbbruch mit jeder anderen Taste ..."; then
if question_answered_with_yes $' ### Google Schriften ###\nGeben Sie j oder n ein und die Eingabetaste,\nAbbruch mit jeder anderen Taste ...'; then
echo
echo "### Google Schriften ###"
@@ -117,7 +117,7 @@ if question_answered_with_yes " ### Google Schriften ###\nGeben Sie j oder n ein
echo ""
echo "$fGoogleSchriften nicht gefunden."
echo " soll das Archiv "google-fonts.tar.gz" von Github heruntergeladen werden? Es ist ca. 1,4GB gross! "
if question_answered_with_yes " ### Download Google Schriften ###\nGeben Sie j oder n ein und die Eingabetaste,\nAbbruch mit jeder anderen Taste ..."; then
if question_answered_with_yes $' ### Download Google Schriften ###\nGeben Sie j oder n ein und die Eingabetaste,\nAbbruch mit jeder anderen Taste ...'; then
_wgeturl="https://github.com/google/fonts/archive/main.tar.gz"
echo "Connecting to Github server to download fonts..."
wget "$_wgeturl" -O "$_gf.tar.gz"
@@ -151,7 +151,7 @@ fi
echo
echo
echo "#### Chromium Browser installieren:"
if question_answered_with_yes " ### Chromium ###\nGeben Sie j oder n ein und die Eingabetaste,\nAbbruch mit jeder anderen Taste ..."; then
if question_answered_with_yes $' ### Chromium ###\nGeben Sie j oder n ein und die Eingabetaste,\nAbbruch mit jeder anderen Taste ...'; then
echo "### Chromium ###"
sudo apt install chromium-browser
sudo apt install chromium
@@ -160,7 +160,7 @@ fi
echo
echo
echo "#### Vivaldi Browser installieren:"
if question_answered_with_yes " ### Vivaldi ###\nGeben Sie j oder n ein und die Eingabetaste,\nAbbruch mit jeder anderen Taste ..."; then
if question_answered_with_yes $' ### Vivaldi ###\nGeben Sie j oder n ein und die Eingabetaste,\nAbbruch mit jeder anderen Taste ...'; then
echo "### ###"
echo "## nötige Zusatzpakete installieren"
sudo apt install dirmngr ca-certificates software-properties-common apt-transport-https curl -y
@@ -183,7 +183,7 @@ fi
echo
echo
echo "####Signal für Desktop (die Nutzung setzt eine Signal-Installation auf einem Android- Oder Apple-Gerät voraus!)#### "
if question_answered_with_yes " ### Signal ###\nGeben Sie j oder n ein und die Eingabetaste,\nAbbruch mit jeder anderen Taste ..."; then
if question_answered_with_yes $' ### Signal ###\nGeben Sie j oder n ein und die Eingabetaste,\nAbbruch mit jeder anderen Taste ...'; then
echo "### ###"
echo "## zusätzliches Repository nötig!
## NOTE: These instructions only work for 64-bit Debian-based
@@ -210,7 +210,7 @@ echo
echo "Achtung! Es kann vorkommen, dass die Taskleiste nach diesem Schritt verschwunden ist."
echo "Ein Abmelden und Wiederanmelden des Benutzers oder ein Reboot behebt das Problem."
echo
if question_answered_with_yes " ### Panel ###\nGeben Sie j oder n ein und die Eingabetaste,\nAbbruch mit jeder anderen Taste ..."; then
if question_answered_with_yes $' ### Panel ###\nGeben Sie j oder n ein und die Eingabetaste,\nAbbruch mit jeder anderen Taste ...'; then
echo "### ###"
echo "## Austausch der Panel-Konfigurationsdatei:"
xfce4-panel-profiles load current-config.tar.bz2
@@ -231,6 +231,6 @@ echo
echo "Wenn ### Google-Schriften ### installiert wurden: Anpassung der Standardschriften und/oder das Erstellen der Ersetzungstabelle in Libre Office, falls gewünscht."
echo
echo
if question_answered_with_yes " ### Um dieses Fenster zu schliessen, \"Enter\" drücken ###"; then
if question_answered_with_yes $' ### Um dieses Fenster zu schliessen, "Enter" drücken ###'; then
exit 0
fi
+18
View File
@@ -0,0 +1,18 @@
# Post-Installation Script
This directory contains all files belonging to the Linux Mint XFCE post-installation script.
## Usage
Run the main script:
```bash
cd post_installation_script
bash 20251212_Nachinstallationsarbeiten_LC_Esslingen_XFCE_v8.sh
```
The script is interactive and will prompt for confirmation before each installation step.
## Testing
See `../post_installation_script_test/README.md` for container-based testing instructions.
+4
View File
@@ -0,0 +1,4 @@
#!/bin/bash
# Create test image from Dockerfile
docker build -t mint-script-test -f Dockerfile .
@@ -0,0 +1,7 @@
#!/bin/bash
# Start container with the test image (interactive shell)
docker run -it --rm \
--cap-drop ALL --security-opt no-new-privileges --tmpfs /tmp:rw \
-v "$(pwd)/../post_installation_script/20251212_Nachinstallationsarbeiten_LC_Esslingen_XFCE_v8.sh":/workspace/script.sh:ro \
mint-script-test
+41
View File
@@ -0,0 +1,41 @@
FROM ubuntu:22.04
# Minimal image for safe simulation of apt installs.
RUN apt-get update && apt-get install -y --no-install-recommends \
bash wget tar curl gnupg ca-certificates apt-utils apt coreutils file procps && \
apt-get clean && rm -rf /var/lib/apt/lists/*
# sudo wrapper: simulate apt installs and avoid making changes to the image
RUN cat > /usr/local/bin/sudo <<'EOF'
#!/bin/sh
# sudo wrapper for simulation:
# - simulate installs with `apt-get -s install ...`
# - run `apt-get update` quietly (needed so apt -s has metadata)
# - otherwise echo the command (no-op)
cmd="$1"
arg2="${2:-}"
if [ "$cmd" = "apt" ] || [ "$cmd" = "apt-get" ]; then
if [ "$arg2" = "install" ]; then
shift 2
echo "[sudo-wrapper] simulating: apt-get -s install $@"
apt-get -s install "$@"
exit $?
elif [ "$arg2" = "update" ]; then
# do not run update at runtime (may require extra privileges); simulate instead
echo "[sudo-wrapper] simulating: apt-get update (no-op in container)"
exit 0
else
echo "[sudo-wrapper] would run: $@"
exit 0
fi
else
echo "[sudo-wrapper] would run: $@"
exit 0
fi
EOF
RUN chmod +x /usr/local/bin/sudo
ENV PATH=/usr/local/bin:$PATH
WORKDIR /workspace
ENTRYPOINT ["/bin/bash"]
+60
View File
@@ -0,0 +1,60 @@
# Post-Installation Script Testing
This directory contains everything needed to test the post-installation script in a safe, isolated container environment.
## Contents
- `Dockerfile` - Container image definition for testing
- `01_create_image.sh` - script for creating container image locally
- `02_start_container_with_image.sh` - script for starting container from created image
## Purpose
Provides a reproducible testing environment that allows:
- Running the post-installation script without affecting the host system
- Simulating `apt` installations (safe, no real package changes)
- Testing script logic, prompts, and error handling
- Validating syntax and tracing execution
## Features
The Dockerfile includes:
- Ubuntu 22.04 base image
- Simulated `sudo` wrapper that runs `apt-get -s install` (simulates installs without making changes)
- Useful utilities: `bash`, `wget`, `tar`, `curl`, `gnupg`, `ca-certificates`, `file`, `procps`
## Usage
### Build the test image
Run the prepared shell script to build the image
```bash
cd post_installation_script_test
sh 01_create_image.sh
```
### Start a container for testing
Run the prepared shell script start a new container for testing based in the
image and remove container after it is stopped. After container is started an interactive session is started into the container.
```bash
cd post_installation_script_test
sh 02_start_container_with_image.sh
```
### Test the script file in the running container
After container is started an interactive session was started in the container and the script can be started for testing
```bash
sh script.sh
```
## Security Notes
- The script is mounted read-only (`:ro` flag) to prevent container from modifying host files
- Container runs with reduced privileges (`--cap-drop ALL --security-opt no-new-privileges`)
- The `sudo` wrapper simulates apt operations, so no packages are actually installed
- Use `--tmpfs /tmp:rw` for any temporary writes inside the container