#!/usr/bin/env bash # test-dev-env.sh - Integration tests for dev dev environment # Run from local machine: ./tests/test-dev-env.sh [username] [ssh-key] # Default username: dantest set -euo pipefail SERVER="45.77.205.49" USER="${1:-dantest}" SSH_KEY="${2:-}" # Build SSH options SSH_OPTS="-o ConnectTimeout=5" if [ -n "$SSH_KEY" ]; then SSH_OPTS="$SSH_OPTS -i $SSH_KEY" fi ssh_cmd() { ssh $SSH_OPTS "${USER}@${SERVER}" "$@" } PASS=0 FAIL=0 red() { echo -e "\033[0;31m$1\033[0m"; } green() { echo -e "\033[0;32m$1\033[0m"; } yellow() { echo -e "\033[1;33m$1\033[0m"; } pass() { PASS=$((PASS + 1)); green " PASS: $1"; } fail() { FAIL=$((FAIL + 1)); red " FAIL: $1"; } skip() { yellow " SKIP: $1"; } echo "==========================================" echo "Dev Environment Tests" echo "Server: $SERVER" echo "User: $USER" echo "==========================================" echo "" # --------------------------------------------- echo "## 1. SSH Connectivity" # --------------------------------------------- if ssh_cmd 'echo ok' &>/dev/null; then pass "SSH connection as $USER" else fail "SSH connection as $USER" echo " Hint: Check SSH key is configured for $USER" echo " Usage: $0 [/path/to/key]" exit 1 fi # --------------------------------------------- echo "" echo "## 2. nix-ld (VS Code Remote-SSH support)" # --------------------------------------------- if ssh_cmd 'test -L /lib64/ld-linux-x86-64.so.2' &>/dev/null; then pass "nix-ld symlink exists" else fail "nix-ld symlink missing" fi # Test with a simple pre-compiled binary (curl is dynamically linked) if ssh_cmd 'file /run/current-system/sw/bin/curl | grep -q "dynamically linked"' &>/dev/null; then pass "Dynamic binaries available" else skip "Could not verify dynamic binary support" fi # --------------------------------------------- echo "" echo "## 3. Devs group membership" # --------------------------------------------- if ssh_cmd 'groups' | grep -q devs; then pass "User in devs group" else fail "User NOT in devs group" fi # --------------------------------------------- echo "" echo "## 4. Slack tokens accessible" # --------------------------------------------- if ssh_cmd 'test -r /etc/slack-dev.env'; then pass "Slack env file readable" else fail "Slack env file NOT readable (check group permissions)" fi if ssh_cmd 'source /etc/slack-dev.env && test -n "$SLACK_BOT_TOKEN"' &>/dev/null; then pass "SLACK_BOT_TOKEN set" else fail "SLACK_BOT_TOKEN not set" fi if ssh_cmd 'source /etc/slack-dev.env && test -n "$SLACK_APP_TOKEN"' &>/dev/null; then pass "SLACK_APP_TOKEN set" else fail "SLACK_APP_TOKEN not set" fi # --------------------------------------------- echo "" echo "## 5. Python environment" # --------------------------------------------- if ssh_cmd 'which python3' &>/dev/null; then pass "python3 available" PY_VERSION=$(ssh_cmd 'python3 --version 2>&1') echo " $PY_VERSION" else fail "python3 not found" fi if ssh_cmd 'uv --version' &>/dev/null; then UV_VERSION=$(ssh_cmd 'uv --version 2>&1') pass "uv available ($UV_VERSION)" else fail "uv not available" fi # --------------------------------------------- echo "" echo "## 6. AI coding tools" # --------------------------------------------- if ssh_cmd 'which opencode' &>/dev/null; then OPENCODE_VERSION=$(ssh_cmd 'opencode --version 2>&1' | head -1) pass "opencode available ($OPENCODE_VERSION)" else fail "opencode not in PATH" fi if ssh_cmd 'which node' &>/dev/null; then NODE_VERSION=$(ssh_cmd 'node --version 2>&1') pass "nodejs available ($NODE_VERSION) - for npm install of claude/gemini/codex" else fail "nodejs not in PATH" fi # --------------------------------------------- echo "" echo "## 7. Slack API connectivity" # --------------------------------------------- echo " Testing Slack API auth (this may take a moment)..." SLACK_TEST=$(ssh_cmd 'source /etc/slack-dev.env && python3 -c " import urllib.request import urllib.error import json import os token = os.environ.get(\"SLACK_BOT_TOKEN\", \"\") if not token: print(\"NO_TOKEN\") exit(1) req = urllib.request.Request( \"https://slack.com/api/auth.test\", headers={\"Authorization\": f\"Bearer {token}\"} ) try: with urllib.request.urlopen(req, timeout=10) as resp: data = json.loads(resp.read()) if data.get(\"ok\"): user = data.get(\"user\", \"unknown\") team = data.get(\"team\", \"unknown\") print(f\"OK:{user}@{team}\") else: err = data.get(\"error\", \"unknown\") print(f\"API_ERROR:{err}\") except Exception as e: print(f\"NET_ERROR:{e}\") " 2>&1' || echo "EXEC_ERROR") case "$SLACK_TEST" in OK:*) pass "Slack API auth successful" echo " Authenticated as: ${SLACK_TEST#OK:}" ;; API_ERROR:*) fail "Slack API error: ${SLACK_TEST#API_ERROR:}" ;; NET_ERROR:*) fail "Network error: ${SLACK_TEST#NET_ERROR:}" ;; NO_TOKEN) fail "No SLACK_BOT_TOKEN available" ;; *) fail "Unexpected result: $SLACK_TEST" ;; esac # --------------------------------------------- echo "" echo "==========================================" echo "Results: $PASS passed, $FAIL failed" echo "==========================================" if [ "$FAIL" -gt 0 ]; then exit 1 fi