Add Docker test scripts for setup validation

- Created run-docker-tests.sh to execute setup tests in isolated Docker containers (Ubuntu and Debian).
- Implemented logging functionality to track test results and errors.
- Added startup.sh to ensure proper permissions and run tests within Docker containers.
- Developed test-setup.sh to validate bootstrap.sh and setup.sh scripts, including package availability checks.
- Enhanced error handling and reporting for package installations and missing dependencies.
- Included detailed logging for system information and test results.
This commit is contained in:
Peter Wood
2025-05-12 14:16:03 -04:00
parent 9a941d1752
commit 52492f9218
6 changed files with 0 additions and 0 deletions

80
shell-setup/Dockerfile Normal file
View File

@@ -0,0 +1,80 @@
# Dockerfile to test bootstrap.sh and setup.sh scripts in different environments
# This allows testing the setup process in isolated containers
# Ubuntu test environment
FROM ubuntu:24.04 as ubuntu-test
LABEL description="Ubuntu test environment for shell setup scripts"
# Install minimal dependencies needed to run the test
ENV TZ=America/New_York
ENV DEBIAN_FRONTEND=noninteractive
ARG APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone \
&& apt-get update && apt-get install -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confnew" -y curl git sudo wget
# Pre-install cowsay and lolcat packages for testing
RUN apt-get update && apt-get install -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confnew" -y cowsay lolcat
# Create logs directory with proper permissions
RUN mkdir -p /logs && chmod -R 777 /logs
# Create a test user with sudo permissions
RUN useradd -ms /bin/bash testuser && \
echo "testuser ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/testuser
USER testuser
WORKDIR /home/testuser
# Create directory structure for shell setup
RUN mkdir -p /home/testuser/shell/setup
# Copy test script, startup script, and packages.list
COPY --chown=testuser:testuser test-setup.sh /home/testuser/
COPY --chown=testuser:testuser startup.sh /home/testuser/
COPY --chown=testuser:testuser setup/packages.list /home/testuser/shell/setup/
# Make scripts executable
RUN chmod +x /home/testuser/test-setup.sh
RUN chmod +x /home/testuser/startup.sh
CMD ["/bin/bash", "-c", "./startup.sh"]
# Debian test environment
FROM debian:12 as debian-test
LABEL description="Debian test environment for shell setup scripts"
# Install minimal dependencies needed to run the test
ENV TZ=America/New_York
ENV DEBIAN_FRONTEND=noninteractive
ARG APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone \
&& apt-get update && apt-get install -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confnew" -y curl git sudo wget
# Pre-install cowsay and lolcat packages for testing
RUN apt-get update && apt-get install -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confnew" -y cowsay lolcat
# Create logs directory with proper permissions
RUN mkdir -p /logs && chmod -R 777 /logs
# Create a test user with sudo permissions
RUN useradd -ms /bin/bash testuser && \
echo "testuser ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/testuser
USER testuser
WORKDIR /home/testuser
# Create directory structure for shell setup
RUN mkdir -p /home/testuser/shell/setup
# Copy test script, startup script, and packages.list
COPY --chown=testuser:testuser test-setup.sh /home/testuser/
COPY --chown=testuser:testuser startup.sh /home/testuser/
COPY --chown=testuser:testuser setup/packages.list /home/testuser/shell/setup/
# Make scripts executable
RUN chmod +x /home/testuser/test-setup.sh
RUN chmod +x /home/testuser/startup.sh
CMD ["/bin/bash", "-c", "./startup.sh"]

40
shell-setup/bootstrap.sh Executable file
View File

@@ -0,0 +1,40 @@
#!/bin/bash
DOTFILES_REPO="acedanger/shell"
DOTFILES_BRANCH="main"
DOTFILES_DIR="$HOME/shell"
# Colors for output
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
echo -e "${GREEN}Setting up your system...${NC}"
# Install git if not present
if ! command -v git &>/dev/null; then
echo -e "${YELLOW}Installing git...${NC}"
sudo apt update && sudo apt install -y git
fi
# Create shell directory if it doesn't exist
mkdir -p "$HOME/shell"
# Clone or update repository
if [ -d "$DOTFILES_DIR" ]; then
echo -e "${YELLOW}Updating existing shell repository...${NC}"
cd "$DOTFILES_DIR"
git pull origin $DOTFILES_BRANCH
else
echo -e "${YELLOW}Cloning shell repository...${NC}"
git clone "https://github.com/$DOTFILES_REPO.git" "$DOTFILES_DIR"
cd "$DOTFILES_DIR"
fi
# Make scripts executable
chmod +x "$DOTFILES_DIR/setup/setup.sh"
# Run setup script
"$DOTFILES_DIR/setup/setup.sh"
echo -e "${GREEN}Bootstrap completed! Please restart your terminal for changes to take effect.${NC}"

225
shell-setup/debian-patches.sh Executable file
View File

@@ -0,0 +1,225 @@
#!/bin/bash
# This script applies Debian-specific patches to the setup scripts
# It should be run before bootstrap.sh on Debian systems
set -e # Exit on error
# Colors for output
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Check if running on Debian
if [ -f /etc/os-release ]; then
. /etc/os-release
if [[ "$ID" == "debian" ]]; then
echo -e "${BLUE}Running on Debian $VERSION_ID ($PRETTY_NAME)${NC}"
else
echo -e "${YELLOW}This script is intended for Debian systems but detected $PRETTY_NAME${NC}"
echo -e "${YELLOW}Continue anyway? [y/N]${NC}"
read -r response
if [[ ! "$response" =~ ^([yY][eE][sS]|[yY])$ ]]; then
echo -e "${RED}Exiting...${NC}"
exit 1
fi
fi
fi
# Create a packages mapping file
PATCH_DIR="$HOME/.shell-debian-patches"
mkdir -p "$PATCH_DIR"
echo -e "${YELLOW}Creating Debian package name mappings...${NC}"
cat > "$PATCH_DIR/debian-packages.map" << 'EOF'
# Debian package name mappings
# format: ubuntu-name|debian-name
# bat is called batcat on Debian
bat|batcat
# Keep original names for packages that are the same
git|git
python3|python3
wget|wget
curl|curl
cowsay|cowsay
lolcat|lolcat
fzf|fzf
zsh|zsh
# Different package names for Nala source
software-properties-common|software-properties-common
EOF
# Create a patching script that will be called by setup.sh
echo -e "${YELLOW}Creating Debian patching script...${NC}"
cat > "$PATCH_DIR/apply-debian-patches.sh" << 'EOF'
#!/bin/bash
# Script to apply Debian-specific patches to the setup process
# Colors for output
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
PATCH_DIR="$HOME/.shell-debian-patches"
# Check if running on Debian
if [ -f /etc/os-release ]; then
. /etc/os-release
if [[ "$ID" != "debian" ]]; then
echo -e "${YELLOW}Not running on Debian, skipping patches${NC}"
exit 0
fi
fi
echo -e "${BLUE}Applying Debian-specific patches...${NC}"
# Function to map package names from Ubuntu to Debian
map_package() {
local ubuntu_pkg="$1"
local debian_pkg
# Look for the package in the mapping file
if [ -f "$PATCH_DIR/debian-packages.map" ]; then
debian_pkg=$(grep -v "^#" "$PATCH_DIR/debian-packages.map" | grep "^$ubuntu_pkg|" | cut -d'|' -f2)
fi
# If not found or empty, use the original name
if [ -z "$debian_pkg" ]; then
debian_pkg="$ubuntu_pkg"
fi
echo "$debian_pkg"
}
# Patch the packages.list file if it exists
if [ -f "$HOME/shell/setup/packages.list" ]; then
echo -e "${YELLOW}Patching packages.list for Debian compatibility...${NC}"
# Create a temporary patched file
temp_file=$(mktemp)
# Process each line
while IFS= read -r line; do
# Skip comments and empty lines
if [[ "$line" =~ ^//.*$ ]] || [[ -z "$line" ]]; then
echo "$line" >> "$temp_file"
continue
fi
# Map the package name
debian_pkg=$(map_package "$line")
echo "$debian_pkg" >> "$temp_file"
done < "$HOME/shell/setup/packages.list"
# Backup original and replace with patched version
cp "$HOME/shell/setup/packages.list" "$HOME/shell/setup/packages.list.orig"
mv "$temp_file" "$HOME/shell/setup/packages.list"
echo -e "${GREEN}Patched packages.list for Debian compatibility${NC}"
fi
# Other Debian-specific patches can be added here...
# Add contrib and non-free repositories if they're not already enabled
echo -e "${YELLOW}Checking Debian repositories...${NC}"
if ! grep -q "contrib" /etc/apt/sources.list; then
echo -e "${YELLOW}Adding contrib and non-free repositories...${NC}"
# Create a backup of the original sources.list
sudo cp /etc/apt/sources.list /etc/apt/sources.list.backup
# Add contrib and non-free to each deb line
sudo sed -i 's/main$/main contrib non-free non-free-firmware/g' /etc/apt/sources.list
echo -e "${GREEN}Added contrib and non-free repositories${NC}"
fi
echo -e "${GREEN}Debian patches applied successfully${NC}"
EOF
chmod +x "$PATCH_DIR/apply-debian-patches.sh"
# Create a wrapper script for bootstrap.sh
echo -e "${YELLOW}Creating Debian bootstrap wrapper...${NC}"
cat > "$HOME/debian-bootstrap.sh" << 'EOF'
#!/bin/bash
# Debian wrapper for bootstrap.sh
set -e # Exit on error
# Colors for output
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
PATCH_DIR="$HOME/.shell-debian-patches"
# Apply Debian patches first
if [ -x "$PATCH_DIR/apply-debian-patches.sh" ]; then
echo -e "${BLUE}Applying Debian patches before bootstrap...${NC}"
"$PATCH_DIR/apply-debian-patches.sh"
fi
# Download and run the bootstrap script
echo -e "${BLUE}Running bootstrap script...${NC}"
curl -s https://raw.githubusercontent.com/acedanger/shell/main/bootstrap.sh | bash
# Apply patches again after bootstrap (in case packages.list was just downloaded)
if [ -x "$PATCH_DIR/apply-debian-patches.sh" ]; then
echo -e "${BLUE}Applying Debian patches after bootstrap...${NC}"
"$PATCH_DIR/apply-debian-patches.sh"
fi
echo -e "${GREEN}Debian bootstrap completed!${NC}"
EOF
chmod +x "$HOME/debian-bootstrap.sh"
# Add a hook to setup.sh to call the Debian patch script
echo -e "${YELLOW}Creating setup.sh hook for Debian...${NC}"
cat > "$PATCH_DIR/setup-hook.sh" << 'EOF'
#!/bin/bash
# Hook to modify setup.sh to call Debian patches
if [ -f /etc/os-release ]; then
. /etc/os-release
if [[ "$ID" == "debian" ]]; then
# Modify setup.sh to call Debian patches
if [ -f "$HOME/shell/setup/setup.sh" ]; then
# Check if the patch hasn't been applied yet
if ! grep -q "apply-debian-patches" "$HOME/shell/setup/setup.sh"; then
# Add call to Debian patch script right after the shebang
sed -i '2i\
# Apply Debian patches if available\
if [ -x "$HOME/.shell-debian-patches/apply-debian-patches.sh" ]; then\
echo -e "${YELLOW}Applying Debian-specific patches...${NC}"\
"$HOME/.shell-debian-patches/apply-debian-patches.sh"\
fi' "$HOME/shell/setup/setup.sh"
fi
fi
fi
fi
EOF
chmod +x "$PATCH_DIR/setup-hook.sh"
echo -e "${GREEN}Debian compatibility patch has been set up!${NC}"
echo -e "${YELLOW}To bootstrap your Debian system, run:${NC}"
echo -e " ${BLUE}bash ~/debian-bootstrap.sh${NC}"
echo ""
echo -e "${YELLOW}This has created:${NC}"
echo -e "1. Package name mappings for Debian"
echo -e "2. A patch script for Debian-specific adjustments"
echo -e "3. A Debian-specific bootstrap wrapper"

237
shell-setup/run-docker-tests.sh Executable file
View File

@@ -0,0 +1,237 @@
#!/bin/bash
# Script to run setup tests in Docker containers
# This allows testing the setup process in isolated environments
set -e # Exit on error
# Colors for output
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Check if Docker is installed and working
if ! command -v docker &> /dev/null; then
echo -e "${RED}Error: Docker is not installed. Please install Docker to run tests.${NC}"
exit 1
fi
# Create logs directory at the top level to ensure it exists
LOGS_DIR="$(pwd)/logs"
if [ ! -d "$LOGS_DIR" ]; then
echo -e "${YELLOW}Creating logs directory at: $LOGS_DIR${NC}"
mkdir -p "$LOGS_DIR" || {
echo -e "${RED}Failed to create logs directory! Check permissions.${NC}"
exit 1
}
else
echo -e "${GREEN}Logs directory already exists at: $LOGS_DIR${NC}"
fi
# Ensure the logs directory is writable
if [ ! -w "$LOGS_DIR" ]; then
echo -e "${YELLOW}Setting permissions on logs directory...${NC}"
chmod -R 777 "$LOGS_DIR" || {
echo -e "${RED}Failed to set write permissions on logs directory!${NC}"
exit 1
}
fi
# Create a test file to verify we can write to it
if touch "$LOGS_DIR/test_file" && rm "$LOGS_DIR/test_file"; then
echo -e "${GREEN}Log directory is writable and ready for use${NC}"
else
echo -e "${RED}Cannot write to logs directory even after setting permissions!${NC}"
exit 1
fi
# Check if Docker is running
if ! docker info &>/dev/null; then
echo -e "${YELLOW}Warning: Docker appears to be installed but not running or not properly configured.${NC}"
echo -e "${YELLOW}If using WSL2, ensure Docker Desktop is running with WSL integration enabled.${NC}"
echo -e "${YELLOW}Would you like to run the local test instead? [Y/n]${NC}"
read -r response
if [[ "$response" =~ ^([nN][oO]|[nN])$ ]]; then
echo -e "${RED}Exiting...${NC}"
exit 1
else
echo -e "${BLUE}Running local test instead...${NC}"
./test-setup.sh
exit $?
fi
fi
# Build and run Ubuntu test container
run_ubuntu_test() {
echo -e "\n${BLUE}=== Running test in Ubuntu container ===${NC}"
# Create the logs directory if it doesn't exist
local log_dir="$(pwd)/logs"
mkdir -p "$log_dir" || true
# Use sudo for chmod only if necessary
if [ ! -w "$log_dir" ]; then
echo -e "${YELLOW}Attempting to fix permissions with sudo...${NC}"
sudo chmod -R 777 "$log_dir" 2>/dev/null || {
echo -e "${YELLOW}Could not change permissions with sudo, continuing anyway...${NC}"
}
fi
echo -e "${YELLOW}Logs will be saved to: $log_dir${NC}"
echo -e "${YELLOW}Building Ubuntu test container...${NC}"
docker build --target ubuntu-test -t shell-test:ubuntu .
echo -e "${GREEN}Running tests with package installation...${NC}"
# Create a timestamp for this test run
TEST_TIMESTAMP=$(date +"%Y%m%d-%H%M%S")
echo -e "${YELLOW}Test run timestamp: $TEST_TIMESTAMP${NC}"
# Run container with proper volume mount and add environment variable for timestamp
docker run --rm -it \
-e TEST_TIMESTAMP="$TEST_TIMESTAMP" \
-e CONTAINER_TYPE="ubuntu" \
-v "$log_dir:/logs:z" \
shell-test:ubuntu
# Check if logs were created
if ls "$log_dir"/setup-test-*"$TEST_TIMESTAMP"* &>/dev/null 2>&1; then
echo -e "${GREEN}Test logs successfully created in host directory${NC}"
else
echo -e "${YELLOW}Warning: No log files found matching timestamp $TEST_TIMESTAMP${NC}"
echo -e "${YELLOW}This may indicate issues with volume mounting or permissions${NC}"
echo -e "${YELLOW}Contents of log directory:${NC}"
ls -la "$log_dir" || echo "Cannot list directory contents"
fi
echo -e "${BLUE}Test completed. Check logs in $log_dir directory${NC}"
}
# Build and run Debian test container
run_debian_test() {
echo -e "\n${BLUE}=== Running test in Debian container ===${NC}"
# Create the logs directory if it doesn't exist
local log_dir="$(pwd)/logs"
mkdir -p "$log_dir" || true
# Use sudo for chmod only if necessary
if [ ! -w "$log_dir" ]; then
echo -e "${YELLOW}Attempting to fix permissions with sudo...${NC}"
sudo chmod -R 777 "$log_dir" 2>/dev/null || {
echo -e "${YELLOW}Could not change permissions with sudo, continuing anyway...${NC}"
}
fi
echo -e "${YELLOW}Logs will be saved to: $log_dir${NC}"
echo -e "${YELLOW}Building Debian test container...${NC}"
docker build --target debian-test -t shell-test:debian .
echo -e "${GREEN}Running tests with package installation...${NC}"
# Create a timestamp for this test run
TEST_TIMESTAMP=$(date +"%Y%m%d-%H%M%S")
echo -e "${YELLOW}Test run timestamp: $TEST_TIMESTAMP${NC}"
# Run container with proper volume mount and add environment variable for timestamp
docker run --rm -it \
-e TEST_TIMESTAMP="$TEST_TIMESTAMP" \
-e CONTAINER_TYPE="debian" \
-v "$log_dir:/logs:z" \
shell-test:debian
# Check if logs were created
if ls "$log_dir"/setup-test-*"$TEST_TIMESTAMP"* &>/dev/null 2>&1; then
echo -e "${GREEN}Test logs successfully created in host directory${NC}"
else
echo -e "${YELLOW}Warning: No log files found matching timestamp $TEST_TIMESTAMP${NC}"
echo -e "${YELLOW}This may indicate issues with volume mounting or permissions${NC}"
echo -e "${YELLOW}Contents of log directory:${NC}"
ls -la "$log_dir" || echo "Cannot list directory contents"
fi
echo -e "${BLUE}Test completed. Check logs in $log_dir directory${NC}"
}
# Full test with bootstrap script
run_full_test() {
local distro=$1
local tag_name=$(echo $distro | sed 's/:/-/g') # Replace colon with hyphen for tag
echo -e "\n${BLUE}=== Running full bootstrap test in $distro container ===${NC}"
# Create a Dockerfile for full test
cat > Dockerfile.fulltest <<EOF
FROM $distro
LABEL description="$distro full test environment for bootstrap.sh script"
# Install minimal dependencies needed to run the bootstrap
ENV TZ=America/New_York
ENV DEBIAN_FRONTEND=noninteractive
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone \
&& apt-get update && apt-get install -y curl git sudo wget
# Create a test user with sudo permissions
RUN useradd -ms /bin/bash testuser && \\
echo "testuser ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/testuser
# Create directory structure for setup files
RUN mkdir -p /home/testuser/shell
# Copy test script for post-bootstrap validation
COPY --chown=testuser:testuser test-setup.sh /home/testuser/
# Copy entire repo structure to ensure we have all needed files
COPY --chown=testuser:testuser . /home/testuser/shell/
USER testuser
WORKDIR /home/testuser
# Make the script executable
RUN chmod +x /home/testuser/test-setup.sh
# Run tests before and after bootstrap to verify package installation
CMD ["/bin/bash", "-c", "echo -e '\\n\\nRunning pre-bootstrap tests...' && ./test-setup.sh && echo -e '\\n\\nRunning bootstrap...' && /home/testuser/shell/bootstrap.sh && echo -e '\\n\\nRunning post-bootstrap tests...' && ./test-setup.sh"]
EOF
# Build and run the container
# Create the logs directory if it doesn't exist
mkdir -p "$(pwd)/logs"
docker build -f Dockerfile.fulltest -t shell-full-test:$tag_name .
docker run --rm -it -v "$(pwd)/logs:/logs" shell-full-test:$tag_name
# Clean up
rm Dockerfile.fulltest
}
# Parse command line arguments
case "$1" in
ubuntu)
run_ubuntu_test
;;
debian)
run_debian_test
;;
full-ubuntu)
run_full_test "ubuntu:24.04"
;;
full-debian)
run_full_test "debian:12"
;;
all)
run_ubuntu_test
run_debian_test
;;
*)
echo -e "${BLUE}Shell Setup Test Runner${NC}"
echo -e "Usage: $0 [option]"
echo -e "\nOptions:"
echo " ubuntu Run test on Ubuntu container (tests packages and components)"
echo " debian Run test on Debian container (tests packages and components)"
echo " full-ubuntu Run full bootstrap test on Ubuntu container (performs complete installation)"
echo " full-debian Run full bootstrap test on Debian container (performs complete installation)"
echo " all Run tests on both Ubuntu and Debian containers (component tests only)"
echo -e "\nExamples:"
echo -e " $0 ubuntu # Quick test for package availability"
echo -e " $0 full-debian # Test complete bootstrap installation"
;;
esac

75
shell-setup/startup.sh Executable file
View File

@@ -0,0 +1,75 @@
#!/bin/bash
# Startup script for Docker containers to ensure permissions and run tests
# Define colors for output
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${BLUE}=== Container Startup Checks ===${NC}"
# Display system information
echo -e "${BLUE}System information:${NC}"
if [ -f /etc/os-release ]; then
. /etc/os-release
echo -e "- OS: ${GREEN}$PRETTY_NAME${NC}"
else
echo -e "- OS: ${YELLOW}Unknown${NC}"
fi
# Ensure packages.list is available
echo -e "${BLUE}Checking for packages.list:${NC}"
if [ -f "$HOME/shell/setup/packages.list" ]; then
echo -e "- packages.list: ${GREEN}Found${NC}"
# Count packages in list (excluding comments and empty lines)
pkg_count=$(grep -v '^//' "$HOME/shell/setup/packages.list" | grep -v -e '^$' | wc -l)
echo -e "- Package count: ${GREEN}$pkg_count packages${NC}"
else
echo -e "- packages.list: ${RED}Not found${NC}"
echo "Error: Could not find packages.list file. Tests will fail."
fi
# Ensure logs directory has correct permissions
echo -e "${BLUE}Setting up logs directory:${NC}"
if [ -d "/logs" ]; then
echo -e "- Logs directory: ${GREEN}Found${NC}"
# Check ownership and permissions
logs_owner=$(stat -c '%U:%G' /logs)
echo -e "- Current ownership: $logs_owner"
echo "- Setting permissions on /logs directory..."
sudo chown -R $(whoami):$(whoami) /logs 2>/dev/null || echo -e "${YELLOW}Failed to set ownership${NC}"
sudo chmod -R 777 /logs 2>/dev/null || echo -e "${YELLOW}Failed to set permissions${NC}"
# Verify permissions are correct
if [ -w "/logs" ]; then
echo -e "- Write permission: ${GREEN}OK${NC}"
# Create a test file to really verify we can write
if touch "/logs/test_file" 2>/dev/null; then
echo -e "- Test write: ${GREEN}Succeeded${NC}"
rm -f "/logs/test_file"
else
echo -e "- Test write: ${RED}Failed${NC}"
fi
else
echo -e "- Write permission: ${RED}Failed${NC}"
fi
else
echo -e "- Logs directory: ${YELLOW}Not found${NC}"
echo "- Creating /logs directory..."
if sudo mkdir -p /logs && sudo chown -R $(whoami):$(whoami) /logs && sudo chmod -R 777 /logs; then
echo -e "- Created logs directory with proper permissions: ${GREEN}Success${NC}"
else
echo -e "- Creating logs directory: ${RED}Failed${NC}"
echo "Warning: Logs will be saved inside container only"
fi
fi
echo -e "${BLUE}=== Starting Test Script ===${NC}"
# Run the test script
./test-setup.sh

764
shell-setup/test-setup.sh Executable file
View File

@@ -0,0 +1,764 @@
#!/bin/bash
# Script to test bootstrap.sh and setup.sh scripts in different environments
# This script can be run on different systems to validate the setup process
# NOTE: We don't use 'set -e' to allow testing all packages even if some fail
# Colors for output
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Maximum number of installation attempts
MAX_INSTALL_ATTEMPTS=3
CURRENT_ATTEMPT=1
# Log file
# Create logs directory if it doesn't exist and is writable
# First, try creating the logs directory in case it doesn't exist
if [ -d "/logs" ] || mkdir -p /logs 2>/dev/null; then
if [ -w "/logs" ]; then
LOGS_DIR="/logs"
echo -e "${GREEN}Logs will be saved to host system at ./logs/${NC}"
else
echo -e "${YELLOW}Warning: /logs directory exists but is not writable${NC}"
sudo chmod -R 777 /logs 2>/dev/null || true
if [ -w "/logs" ]; then
LOGS_DIR="/logs"
echo -e "${GREEN}Logs will be saved to host system at ./logs/ (permissions fixed)${NC}"
else
LOGS_DIR="/tmp"
echo -e "${RED}Warning: Could not fix /logs permissions. Logs will be saved to $LOGS_DIR (container only)${NC}"
fi
fi
else
LOGS_DIR="/tmp"
echo -e "${YELLOW}Warning: /logs directory not available or could not be created. Logs will be saved to $LOGS_DIR (container only)${NC}"
fi
# Use the timestamp from environment variable if set, otherwise generate a new one
TIMESTAMP="${TEST_TIMESTAMP:-$(date +"%Y%m%d-%H%M%S")}"
CONTAINER_INFO="${CONTAINER_TYPE:+$CONTAINER_TYPE-}"
LOG_FILE="$LOGS_DIR/setup-test-${CONTAINER_INFO}${TIMESTAMP}.log"
echo "Starting setup test at $(date)" > "$LOG_FILE" || {
echo -e "${RED}Error: Failed to write to log file at $LOG_FILE. Check permissions.${NC}"
ls -la "$LOGS_DIR" 2>/dev/null || echo "Cannot list logs directory contents"
LOGS_DIR="/tmp"
LOG_FILE="$LOGS_DIR/setup-test-${CONTAINER_INFO}${TIMESTAMP}.log"
echo -e "${YELLOW}Attempting to use fallback log location: $LOG_FILE${NC}"
echo "Starting setup test at $(date)" > "$LOG_FILE"
}
# Identify the system
echo -e "${BLUE}=== System Information ===${NC}"
if [ -f /etc/os-release ]; then
. /etc/os-release
echo -e "Detected: ${GREEN}$PRETTY_NAME${NC}"
echo "Testing on: $PRETTY_NAME" >> "$LOG_FILE"
else
echo -e "${RED}Could not determine OS${NC}"
echo "Could not determine OS" >> "$LOG_FILE"
exit 1
fi
# Determine if this is a pre-bootstrap or post-bootstrap test
TEST_STAGE="Unknown"
if [ -d "$HOME/shell" ] && [ -f "$HOME/shell/bootstrap.sh" ] && [ -d "$HOME/shell/setup" ] && [ -f "$HOME/shell/setup/setup.sh" ]; then
# Check if there are any signs that bootstrap has been completed
if [ -d "$HOME/.oh-my-zsh" ] || [ -f "$HOME/.zshrc" ] || [ -d "$HOME/.nvm" ]; then
TEST_STAGE="Post-Bootstrap"
else
TEST_STAGE="Mid-Bootstrap"
fi
else
TEST_STAGE="Pre-Bootstrap"
fi
echo -e "Test Stage: ${GREEN}$TEST_STAGE${NC}"
echo "Test Stage: $TEST_STAGE" >> "$LOG_FILE"
# Check if this is running in a test environment (container or VM)
ENV_TYPE="Unknown"
if [ -f /.dockerenv ]; then
ENV_TYPE="Docker container"
elif grep -q "^flags.*hypervisor" /proc/cpuinfo 2>/dev/null; then
ENV_TYPE="Virtual machine"
else
ENV_TYPE="Physical machine"
fi
echo -e "Environment: ${GREEN}$ENV_TYPE${NC}"
echo "Environment: $ENV_TYPE" >> "$LOG_FILE"
# Initialize arrays for tracking
missing_packages=()
installed_this_round=()
failed_packages=()
# Helper functions
check_command() {
command -v "$1" &> /dev/null
}
test_package() {
local pkg=$1
local cmd=${2:-$1}
local alt_cmd=$3 # Optional alternative command name
echo -en "Testing if $pkg is installed... "
# Special case for cowsay and lolcat which might be in different paths
if [ "$pkg" = "cowsay" ]; then
if check_command "$cmd"; then
echo -e "${GREEN}${NC}"
echo "$pkg: Installed (found in PATH as $cmd)" >> "$LOG_FILE"
return 0
elif [ -x "/usr/games/cowsay" ]; then
echo -e "${GREEN}${NC} (in /usr/games)"
echo "$pkg: Installed (found in /usr/games/)" >> "$LOG_FILE"
# Create a symlink to make it available in PATH for other scripts
if [ ! -e "$HOME/.local/bin" ]; then
mkdir -p "$HOME/.local/bin"
fi
if [ ! -e "$HOME/.local/bin/cowsay" ] && [ -w "$HOME/.local/bin" ]; then
ln -sf /usr/games/cowsay "$HOME/.local/bin/cowsay"
echo "Created symlink for cowsay in $HOME/.local/bin" >> "$LOG_FILE"
fi
return 0
fi
elif [ "$pkg" = "lolcat" ]; then
if check_command "$cmd"; then
echo -e "${GREEN}${NC}"
echo "$pkg: Installed (found in PATH as $cmd)" >> "$LOG_FILE"
return 0
elif [ -x "/usr/games/lolcat" ]; then
echo -e "${GREEN}${NC} (in /usr/games)"
echo "$pkg: Installed (found in /usr/games/)" >> "$LOG_FILE"
# Create a symlink to make it available in PATH for other scripts
if [ ! -e "$HOME/.local/bin" ]; then
mkdir -p "$HOME/.local/bin"
fi
if [ ! -e "$HOME/.local/bin/lolcat" ] && [ -w "$HOME/.local/bin" ]; then
ln -sf /usr/games/lolcat "$HOME/.local/bin/lolcat"
echo "Created symlink for lolcat in $HOME/.local/bin" >> "$LOG_FILE"
fi
return 0
fi
elif check_command "$cmd"; then
echo -e "${GREEN}${NC}"
echo "$pkg: Installed (as $cmd)" >> "$LOG_FILE"
return 0
elif [ -n "$alt_cmd" ] && check_command "$alt_cmd"; then
echo -e "${GREEN}${NC} (as $alt_cmd)"
echo "$pkg: Installed (as $alt_cmd)" >> "$LOG_FILE"
return 0
else
echo -e "${RED}${NC}"
echo "$pkg: Missing" >> "$LOG_FILE"
return 1
fi
# Note: The calling code will handle the failure and continue testing
}
test_file_exists() {
local file=$1
local description=${2:-"File exists"}
echo -en "Testing if $file exists... "
if [ -e "$file" ]; then
echo -e "${GREEN}${NC}"
echo "$description: Yes" >> "$LOG_FILE"
return 0
else
echo -e "${RED}${NC}"
echo "$description: No" >> "$LOG_FILE"
return 1
fi
}
# Get actual package name based on distribution
get_package_name() {
local pkg=$1
# Handle Debian-specific package name differences
if [[ "$ID" == "debian" ]]; then
case "$pkg" in
"bat")
echo "batcat"
;;
*)
echo "$pkg"
;;
esac
else
# Default to the original package name for Ubuntu and others
echo "$pkg"
fi
}
# Function to install missing packages
install_missing_packages() {
local packages=("$@")
local install_cmd_name
local install_cmd=()
if [ ${#packages[@]} -eq 0 ]; then
echo -e "${GREEN}No packages to install${NC}"
echo "No packages to install" >> "$LOG_FILE"
return 0
fi
echo -e "\n${BLUE}=== Installing missing packages (Attempt $CURRENT_ATTEMPT of $MAX_INSTALL_ATTEMPTS) ===${NC}"
echo "=== Installing missing packages (Attempt $CURRENT_ATTEMPT of $MAX_INSTALL_ATTEMPTS) ===" >> "$LOG_FILE"
# Determine the best installation command
if check_command nala; then
install_cmd=(sudo DEBIAN_FRONTEND=noninteractive nala install -y)
install_cmd_name="nala"
echo -e "${GREEN}Using nala for package installation${NC}"
echo "Using nala for package installation" >> "$LOG_FILE"
else
install_cmd=(sudo DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confnew" install -y)
install_cmd_name="apt-get"
echo -e "${YELLOW}Using apt-get for package installation${NC}"
echo "Using apt-get for package installation" >> "$LOG_FILE"
fi
# Convert package list to distribution-specific names
local install_list=()
for pkg in "${packages[@]}"; do
local actual_pkg=$(get_package_name "$pkg")
install_list+=("$actual_pkg")
done
# Update package lists
echo -e "${YELLOW}Updating package lists...${NC}"
echo "Updating package lists" >> "$LOG_FILE"
if check_command nala; then
echo -e "${GREEN}Running: sudo DEBIAN_FRONTEND=noninteractive nala update${NC}"
sudo DEBIAN_FRONTEND=noninteractive nala update | tee -a "$LOG_FILE"
else
echo -e "${GREEN}Running: sudo DEBIAN_FRONTEND=noninteractive apt-get update${NC}"
sudo DEBIAN_FRONTEND=noninteractive apt-get update | tee -a "$LOG_FILE"
fi
# Install packages
echo -e "${YELLOW}Installing packages: ${install_list[*]}${NC}"
echo "Installing packages: ${install_list[*]}" >> "$LOG_FILE"
# Show the exact command being run for debugging
echo -e "${BLUE}Running: ${install_cmd[*]} ${install_list[*]}${NC}"
# Execute the install command with the package list
if ! "${install_cmd[@]}" "${install_list[@]}" 2>&1 | tee -a "$LOG_FILE"; then
echo -e "${RED}Failed to install some packages. Check the log for details.${NC}"
echo "Failed to install some packages" >> "$LOG_FILE"
# Try to install packages one by one to identify problematic ones
echo -e "${YELLOW}Trying to install packages individually...${NC}"
echo "Trying to install packages individually" >> "$LOG_FILE"
installed_this_round=()
local failed_this_round=()
for i in "${!packages[@]}"; do
local pkg="${packages[$i]}"
local actual_pkg="${install_list[$i]}"
echo -en "Installing $pkg as $actual_pkg... "
if "${install_cmd[@]}" "$actual_pkg" >> "$LOG_FILE" 2>&1; then
echo -e "${GREEN}${NC}"
echo "$pkg: Installed successfully" >> "$LOG_FILE"
installed_this_round+=("$pkg")
else
echo -e "${RED}${NC}"
echo "$pkg: Installation failed" >> "$LOG_FILE"
failed_this_round+=("$pkg")
fi
done
failed_packages=("${failed_this_round[@]}")
return 1
else
echo -e "${GREEN}Successfully installed all packages!${NC}"
echo "Successfully installed all packages" >> "$LOG_FILE"
installed_this_round=("${packages[@]}")
return 0
fi
}
# Create a temporary backup of .zshrc if it exists
if [ -f "$HOME/.zshrc" ]; then
cp "$HOME/.zshrc" "$HOME/.zshrc.test_backup"
echo "Backed up existing .zshrc" >> "$LOG_FILE"
fi
# Main testing sequence
echo -e "\n${BLUE}=== Testing bootstrap.sh ===${NC}"
echo "=== Testing bootstrap.sh ===" >> "$LOG_FILE"
# Get the bootstrap script if it doesn't exist locally
if [ ! -f "$HOME/shell/bootstrap.sh" ]; then
echo -e "${YELLOW}Downloading bootstrap.sh...${NC}"
echo "Downloading bootstrap.sh" >> "$LOG_FILE"
curl -s -o /tmp/bootstrap.sh https://raw.githubusercontent.com/acedanger/shell/main/bootstrap.sh || {
echo -e "${RED}Failed to download bootstrap.sh${NC}"
echo "Failed to download bootstrap.sh" >> "$LOG_FILE"
exit 1
}
chmod +x /tmp/bootstrap.sh
else
echo -e "${YELLOW}Using local bootstrap.sh${NC}"
echo "Using local bootstrap.sh" >> "$LOG_FILE"
cp "$HOME/shell/bootstrap.sh" /tmp/bootstrap.sh
fi
# Run bootstrap in test mode (no actual execution)
echo -e "${YELLOW}Analyzing bootstrap script...${NC}"
bash -n /tmp/bootstrap.sh
if [ $? -eq 0 ]; then
echo -e "${GREEN}Bootstrap script syntax is valid${NC}"
echo "Bootstrap script syntax: Valid" >> "$LOG_FILE"
else
echo -e "${RED}Bootstrap script has syntax errors${NC}"
echo "Bootstrap script syntax: Invalid" >> "$LOG_FILE"
exit 1
fi
echo -e "\n${BLUE}=== Testing setup.sh ===${NC}"
echo "=== Testing setup.sh ===" >> "$LOG_FILE"
# Check setup.sh script if available
if [ -f "$HOME/shell/setup/setup.sh" ]; then
echo -e "${YELLOW}Analyzing setup script...${NC}"
bash -n "$HOME/shell/setup/setup.sh"
if [ $? -eq 0 ]; then
echo -e "${GREEN}Setup script syntax is valid${NC}"
echo "Setup script syntax: Valid" >> "$LOG_FILE"
else
echo -e "${RED}Setup script has syntax errors${NC}"
echo "Setup script syntax: Invalid" >> "$LOG_FILE"
exit 1
fi
else
echo -e "${YELLOW}Setup script not available locally. Will be downloaded by bootstrap.${NC}"
echo "Setup script not available locally" >> "$LOG_FILE"
fi
echo -e "\n${BLUE}=== Testing Debian compatibility ===${NC}"
echo "=== Testing Debian compatibility ===" >> "$LOG_FILE"
# Check for Debian-specific commands used in scripts
echo -en "Checking if apt is available... "
if check_command apt; then
echo -e "${GREEN}${NC}"
echo "apt: Available" >> "$LOG_FILE"
else
echo -e "${RED}${NC} (Scripts may not work here)"
echo "apt: Not available" >> "$LOG_FILE"
fi
# Check if the package list is valid for this system
if [ -f "$HOME/shell/setup/packages.list" ]; then
echo -e "${YELLOW}Testing package availability in repositories:${NC}"
echo "Testing package availability:" >> "$LOG_FILE"
# Exclude commented lines and empty lines
packages=$(grep -v '^//' "$HOME/shell/setup/packages.list" | grep -v -e '^$')
for pkg in $packages; do
echo -en "Checking if $pkg is available in repos... "
actual_pkg=$(get_package_name "$pkg")
if apt-cache show "$actual_pkg" &>/dev/null; then
echo -e "${GREEN}${NC}"
echo "$pkg: Available in repos as $actual_pkg" >> "$LOG_FILE"
else
echo -e "${RED}${NC}"
echo "$pkg: Not available in repos" >> "$LOG_FILE"
fi
done
fi
# Main testing and installation loop
while [ $CURRENT_ATTEMPT -le $MAX_INSTALL_ATTEMPTS ]; do
echo -e "\n${BLUE}=== Testing installed components (Attempt $CURRENT_ATTEMPT of $MAX_INSTALL_ATTEMPTS) ===${NC}"
echo "=== Testing installed components (Attempt $CURRENT_ATTEMPT of $MAX_INSTALL_ATTEMPTS) ===" >> "$LOG_FILE"
errors=0
missing_packages=()
# Test core required tools
core_tools=("git" "curl" "wget")
for tool in "${core_tools[@]}"; do
if ! test_package "$tool"; then
((errors++))
missing_packages+=("$tool")
fi
done
# Test if setup has already been run
if [ -d "$HOME/.oh-my-zsh" ]; then
echo -e "Oh My Zsh: ${GREEN}Installed${NC}"
echo "Oh My Zsh: Installed" >> "$LOG_FILE"
else
echo -e "Oh My Zsh: ${YELLOW}Not installed${NC}"
echo "Oh My Zsh: Not installed" >> "$LOG_FILE"
fi
# Check custom packages from packages.list
echo -e "${YELLOW}Testing packages listed in packages.list:${NC}"
echo "Testing packages listed in packages.list:" >> "$LOG_FILE"
if [ -f "$HOME/shell/setup/packages.list" ]; then
# Exclude commented lines and empty lines
packages=$(grep -v '^//' "$HOME/shell/setup/packages.list" | grep -v -e '^$')
for pkg in $packages; do
case "$pkg" in
"bat")
if ! test_package "bat" "bat" "batcat"; then
((errors++))
missing_packages+=("$pkg")
fi
;;
"cowsay")
# Extra debugging for cowsay
echo -e "\n${BLUE}Debugging cowsay package:${NC}" | tee -a "$LOG_FILE"
if [ -f "/usr/games/cowsay" ]; then
echo -e "- Cowsay found at /usr/games/cowsay" | tee -a "$LOG_FILE"
ls -la /usr/games/cowsay | tee -a "$LOG_FILE"
else
echo -e "- Cowsay not found at /usr/games/cowsay" | tee -a "$LOG_FILE"
fi
if check_command cowsay; then
echo -e "- Cowsay found in PATH" | tee -a "$LOG_FILE"
command -v cowsay | tee -a "$LOG_FILE"
else
echo -e "- Cowsay not found in PATH" | tee -a "$LOG_FILE"
fi
if ! test_package "cowsay" "cowsay"; then
((errors++))
missing_packages+=("$pkg")
fi
;;
"lolcat")
# Extra debugging for lolcat
echo -e "\n${BLUE}Debugging lolcat package:${NC}" | tee -a "$LOG_FILE"
if [ -f "/usr/games/lolcat" ]; then
echo -e "- Lolcat found at /usr/games/lolcat" | tee -a "$LOG_FILE"
ls -la /usr/games/lolcat | tee -a "$LOG_FILE"
else
echo -e "- Lolcat not found at /usr/games/lolcat" | tee -a "$LOG_FILE"
fi
if check_command lolcat; then
echo -e "- Lolcat found in PATH" | tee -a "$LOG_FILE"
command -v lolcat | tee -a "$LOG_FILE"
else
echo -e "- Lolcat not found in PATH" | tee -a "$LOG_FILE"
fi
if ! test_package "lolcat" "lolcat"; then
((errors++))
missing_packages+=("$pkg")
fi
;;
*)
if ! test_package "$pkg" "$pkg"; then
((errors++))
missing_packages+=("$pkg")
fi
;;
esac
done
# Report missing packages
if [ ${#missing_packages[@]} -gt 0 ]; then
echo -e "\n${YELLOW}Missing packages:${NC}"
for pkg in "${missing_packages[@]}"; do
echo -e "- ${RED}$pkg${NC}"
done
# Count installed vs. total packages
total_pkgs=$(grep -v '^//' "$HOME/shell/setup/packages.list" | grep -v -e '^$' | wc -l)
installed_pkgs=$((total_pkgs - ${#missing_packages[@]}))
echo -e "${GREEN}$installed_pkgs of $total_pkgs packages installed${NC} (${YELLOW}${#missing_packages[@]} missing${NC})"
echo "$installed_pkgs of $total_pkgs packages installed (${#missing_packages[@]} missing)" >> "$LOG_FILE"
# Install missing packages if we haven't reached the maximum attempts
if [ $CURRENT_ATTEMPT -lt $MAX_INSTALL_ATTEMPTS ]; then
install_missing_packages "${missing_packages[@]}"
echo -e "\n${BLUE}=== Installation Results ===${NC}"
if [ ${#installed_this_round[@]} -gt 0 ]; then
echo -e "${GREEN}Successfully installed:${NC}"
for pkg in "${installed_this_round[@]}"; do
echo -e "- ${GREEN}$pkg${NC}"
done
echo "Successfully installed: ${installed_this_round[*]}" >> "$LOG_FILE"
fi
if [ ${#failed_packages[@]} -gt 0 ]; then
echo -e "${RED}Failed to install:${NC}"
for pkg in "${failed_packages[@]}"; do
echo -e "- ${RED}$pkg${NC}"
done
echo "Failed to install: ${failed_packages[*]}" >> "$LOG_FILE"
fi
CURRENT_ATTEMPT=$((CURRENT_ATTEMPT + 1))
echo -e "\n${YELLOW}Continuing to next test iteration...${NC}"
echo "Continuing to next test iteration" >> "$LOG_FILE"
continue
fi
else
total_pkgs=$(grep -v '^//' "$HOME/shell/setup/packages.list" | grep -v -e '^$' | wc -l)
echo -e "\n${GREEN}All $total_pkgs packages are installed!${NC}"
echo "All $total_pkgs packages are installed" >> "$LOG_FILE"
break
fi
else
echo -e "${RED}packages.list file not found at $HOME/shell/setup/packages.list${NC}"
echo "packages.list file not found" >> "$LOG_FILE"
fi
# If no missing packages or we've reached max attempts, break out of the loop
if [ ${#missing_packages[@]} -eq 0 ] || [ $CURRENT_ATTEMPT -ge $MAX_INSTALL_ATTEMPTS ]; then
break
fi
CURRENT_ATTEMPT=$((CURRENT_ATTEMPT + 1))
done
# Test nvm installation
if [ -d "$HOME/.nvm" ]; then
echo -e "NVM: ${GREEN}Installed${NC}"
echo "NVM: Installed" >> "$LOG_FILE"
# Source NVM
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# Test Node.js installed by NVM
if check_command node; then
node_version=$(node -v)
echo -e "Node.js: ${GREEN}$node_version${NC}"
echo "Node.js: $node_version" >> "$LOG_FILE"
else
echo -e "Node.js: ${RED}Not installed${NC}"
echo "Node.js: Not installed" >> "$LOG_FILE"
((errors++))
fi
else
echo -e "NVM: ${YELLOW}Not installed${NC}"
echo "NVM: Not installed" >> "$LOG_FILE"
fi
# Test zoxide
if test_package "zoxide"; then
echo -e "Zoxide integration: ${GREEN}Available${NC}"
echo "Zoxide integration: Available" >> "$LOG_FILE"
fi
# Test ZSH plugins
zsh_plugins=(
"$HOME/.oh-my-zsh/custom/plugins/zsh-autosuggestions"
"$HOME/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting"
"$HOME/.oh-my-zsh/custom/plugins/zsh-you-should-use"
)
for plugin_dir in "${zsh_plugins[@]}"; do
plugin_name=$(basename "$plugin_dir")
if [ -d "$plugin_dir" ]; then
echo -e "ZSH plugin $plugin_name: ${GREEN}Installed${NC}"
echo "ZSH plugin $plugin_name: Installed" >> "$LOG_FILE"
else
echo -e "ZSH plugin $plugin_name: ${YELLOW}Not installed${NC}"
echo "ZSH plugin $plugin_name: Not installed" >> "$LOG_FILE"
fi
done
# Test dotfile linking
dotfiles=(
"$HOME/.zshrc"
"$HOME/.nanorc"
"$HOME/.profile"
"$HOME/.gitconfig"
)
for dotfile in "${dotfiles[@]}"; do
if [ -L "$dotfile" ]; then
echo -e "Dotfile $dotfile: ${GREEN}Symlinked${NC}"
echo "Dotfile $dotfile: Symlinked" >> "$LOG_FILE"
# Check if symlink is valid
if [ -e "$dotfile" ]; then
target=$(readlink -f "$dotfile")
echo -e " → Links to: ${GREEN}$target${NC}"
echo " → Links to: $target" >> "$LOG_FILE"
else
echo -e "${RED}Broken symlink${NC}"
echo " → Broken symlink" >> "$LOG_FILE"
((errors++))
fi
elif [ -f "$dotfile" ]; then
echo -e "Dotfile $dotfile: ${YELLOW}Exists but not symlinked${NC}"
echo "Dotfile $dotfile: Exists but not symlinked" >> "$LOG_FILE"
else
echo -e "Dotfile $dotfile: ${YELLOW}Not present${NC}"
echo "Dotfile $dotfile: Not present" >> "$LOG_FILE"
fi
done
echo -e "\n${BLUE}=== Summary ===${NC}"
echo "=== Summary ===" >> "$LOG_FILE"
# Test summary
if [ $errors -eq 0 ]; then
echo -e "${GREEN}All critical components and packages passed! Your setup appears to be working correctly.${NC}"
echo "Result: All critical components and packages passed" >> "$LOG_FILE"
else
echo -e "${RED}Found $errors potential issues with your setup.${NC}"
echo "Result: Found $errors potential issues" >> "$LOG_FILE"
# Display missing packages if any
if [ ${#missing_packages[@]} -gt 0 ]; then
echo -e "\n${YELLOW}The following packages were not found:${NC}"
echo "Missing packages:" >> "$LOG_FILE"
for pkg in "${missing_packages[@]}"; do
echo -e " - ${RED}$pkg${NC}"
echo " - $pkg" >> "$LOG_FILE"
done
if [ $CURRENT_ATTEMPT -gt $MAX_INSTALL_ATTEMPTS ]; then
echo -e "\n${RED}Reached maximum installation attempts ($MAX_INSTALL_ATTEMPTS).${NC}"
echo -e "${YELLOW}Some packages could not be installed automatically.${NC}"
echo "Reached maximum installation attempts" >> "$LOG_FILE"
fi
echo -e "\n${BLUE}You can manually install these packages with:${NC}"
echo -e " sudo apt-get install ${missing_packages[*]}"
fi
fi
# Provide more detailed information about log files
if [[ "$LOG_FILE" == "/logs/"* ]]; then
HOST_LOG_FILE="./logs/$(basename "$LOG_FILE")"
echo -e "\n${YELLOW}Complete test log saved to:${NC} $LOG_FILE"
echo -e "${GREEN}This log file is accessible on the host system at:${NC} $HOST_LOG_FILE"
else
echo -e "\n${YELLOW}Complete test log saved to:${NC} $LOG_FILE (in container only)"
echo -e "${YELLOW}Note: This log file will be lost when the container exits."
echo -e "To preserve logs, run with the logs volume mounted using run-docker-tests.sh${NC}"
fi
# Check for Debian-specific issues
if [[ "$ID" == "debian" ]]; then
echo -e "\n${BLUE}=== Debian-Specific Recommendations ===${NC}"
echo "=== Debian-Specific Recommendations ===" >> "$LOG_FILE"
echo "1. Ensure Debian's 'universe' equivalent repositories are enabled (contrib, non-free)"
echo "2. Some packages like 'bat' may have different names in Debian (batcat)"
echo "3. Consider adding Debian-specific adjustments to setup.sh"
# Add specific Debian package name mappings
echo -e "\nOn Debian, you may need these package name adjustments:"
echo " - bat → batcat"
echo " - (add more as needed)"
echo "Debian package name mappings may be required" >> "$LOG_FILE"
fi
# Enhanced testing for bootstrapped environment
check_bootstrapped_environment() {
echo -e "\n${BLUE}=== Checking for bootstrapped environment ===${NC}"
echo "=== Checking for bootstrapped environment ===" >> "$LOG_FILE"
if [ -d "$HOME/shell" ] && [ -f "$HOME/shell/bootstrap.sh" ]; then
echo -e "${GREEN}Environment appears to be bootstrapped:${NC}"
echo "Environment is bootstrapped" >> "$LOG_FILE"
# Check the shell repository structure
if [ -d "$HOME/shell/setup" ] && [ -f "$HOME/shell/setup/setup.sh" ]; then
echo -e " - ${GREEN}Setup directory and script present${NC}"
echo "Setup directory and script: Present" >> "$LOG_FILE"
# Check if setup.sh is executable
if [ -x "$HOME/shell/setup/setup.sh" ]; then
echo -e " - ${GREEN}Setup script is executable${NC}"
echo "Setup script is executable: Yes" >> "$LOG_FILE"
else
echo -e " - ${RED}Setup script is not executable${NC}"
echo "Setup script is executable: No" >> "$LOG_FILE"
fi
else
echo -e " - ${RED}Setup directory or setup.sh missing${NC}"
echo "Setup directory or setup.sh: Missing" >> "$LOG_FILE"
fi
# Check packages.list
if [ -f "$HOME/shell/setup/packages.list" ]; then
echo -e " - ${GREEN}Packages list present${NC}"
echo "Packages list: Present" >> "$LOG_FILE"
# Count packages in list
pkg_count=$(grep -v '^//' "$HOME/shell/setup/packages.list" | grep -v -e '^$' | wc -l)
echo -e " - ${GREEN}Package list contains $pkg_count packages${NC}"
echo "Package list count: $pkg_count" >> "$LOG_FILE"
else
echo -e " - ${RED}Packages list missing${NC}"
echo "Packages list: Missing" >> "$LOG_FILE"
fi
# Check dotfiles directory
if [ -d "$HOME/shell/dotfiles" ]; then
echo -e " - ${GREEN}Dotfiles directory present${NC}"
echo "Dotfiles directory: Present" >> "$LOG_FILE"
# Check if dotfiles are properly symlinked
dotfiles_linked=true
for dotfile in "$HOME/.zshrc" "$HOME/.nanorc" "$HOME/.profile" "$HOME/.gitconfig"; do
if [ -L "$dotfile" ]; then
target=$(readlink -f "$dotfile" 2>/dev/null)
if [[ "$target" == *"shell/dotfiles"* ]]; then
continue
else
dotfiles_linked=false
break
fi
else
dotfiles_linked=false
break
fi
done
if $dotfiles_linked; then
echo -e " - ${GREEN}Dotfiles are properly symlinked${NC}"
echo "Dotfiles symlinked: Yes" >> "$LOG_FILE"
else
echo -e " - ${YELLOW}Some dotfiles are not properly symlinked${NC}"
echo "Dotfiles symlinked: No" >> "$LOG_FILE"
fi
else
echo -e " - ${RED}Dotfiles directory missing${NC}"
echo "Dotfiles directory: Missing" >> "$LOG_FILE"
fi
else
echo -e "${YELLOW}No bootstrapped environment detected${NC}"
echo "No bootstrapped environment detected" >> "$LOG_FILE"
fi
}
# Call the check if we're not in a simple test environment
if [ -d "$HOME/shell" ] && [ -f "$HOME/shell/bootstrap.sh" ]; then
check_bootstrapped_environment
fi
# Restore .zshrc if we backed it up
if [ -f "$HOME/.zshrc.test_backup" ]; then
echo -e "\n${YELLOW}Restoring original .zshrc${NC}"
mv "$HOME/.zshrc.test_backup" "$HOME/.zshrc"
echo "Restored original .zshrc" >> "$LOG_FILE"
fi
echo -e "\n${GREEN}Test completed!${NC}"
echo "Test completed at $(date)" >> "$LOG_FILE"