|
| 1 | +#!/bin/bash |
| 2 | +# |
| 3 | +# Test that Debian packages build, contain expected files, install, and work. |
| 4 | +# |
| 5 | +# Usage: bash tests/test_deb_build.sh |
| 6 | +# |
| 7 | +# Requirements (Linux only): |
| 8 | +# - dpkg-buildpackage, debhelper, fakeroot |
| 9 | +# - Build dependencies listed in debian/control |
| 10 | +# - sudo (for install phase) |
| 11 | +# |
| 12 | + |
| 13 | +set -euo pipefail |
| 14 | + |
| 15 | +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| 16 | +PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" |
| 17 | + |
| 18 | +# --- helpers ---------------------------------------------------------------- |
| 19 | + |
| 20 | +PASS_COUNT=0 |
| 21 | +FAIL_COUNT=0 |
| 22 | +FAILURES="" |
| 23 | + |
| 24 | +log() { |
| 25 | + echo "=== [test_deb_build] $* ===" |
| 26 | +} |
| 27 | + |
| 28 | +check_pass() { |
| 29 | + PASS_COUNT=$((PASS_COUNT + 1)) |
| 30 | + echo " PASS: $*" |
| 31 | +} |
| 32 | + |
| 33 | +check_fail() { |
| 34 | + FAIL_COUNT=$((FAIL_COUNT + 1)) |
| 35 | + FAILURES="${FAILURES} FAIL: $*"$'\n' |
| 36 | + echo " FAIL: $*" |
| 37 | +} |
| 38 | + |
| 39 | +# check_file_in_deb DEB_FILE PATTERN DESCRIPTION |
| 40 | +# Verifies that at least one file matching PATTERN exists in the .deb |
| 41 | +check_file_in_deb() { |
| 42 | + local deb="$1" pattern="$2" desc="$3" |
| 43 | + # Avoid grep -q: with pipefail, early grep exit causes SIGPIPE on dpkg-deb |
| 44 | + if dpkg-deb -c "$deb" | grep -E "$pattern" >/dev/null; then |
| 45 | + check_pass "$desc" |
| 46 | + else |
| 47 | + check_fail "$desc" |
| 48 | + fi |
| 49 | +} |
| 50 | + |
| 51 | +# check_command CMD DESCRIPTION |
| 52 | +# Verifies that a command runs successfully (exit 0) |
| 53 | +check_command() { |
| 54 | + local desc="$2" |
| 55 | + if eval "$1" >/dev/null 2>&1; then |
| 56 | + check_pass "$desc" |
| 57 | + else |
| 58 | + check_fail "$desc" |
| 59 | + fi |
| 60 | +} |
| 61 | + |
| 62 | +summary() { |
| 63 | + echo "" |
| 64 | + log "Results: $PASS_COUNT passed, $FAIL_COUNT failed" |
| 65 | + if [ "$FAIL_COUNT" -gt 0 ]; then |
| 66 | + echo "" |
| 67 | + echo "Failures:" |
| 68 | + printf '%s' "$FAILURES" |
| 69 | + exit 1 |
| 70 | + fi |
| 71 | +} |
| 72 | + |
| 73 | +# --- phase 1: build -------------------------------------------------------- |
| 74 | + |
| 75 | +log "Phase 1: Build Debian packages" |
| 76 | + |
| 77 | +cd "$PROJECT_DIR" |
| 78 | + |
| 79 | +# dpkg-buildpackage -b builds binary-only packages (no .orig.tar.gz needed) |
| 80 | +dpkg-buildpackage -b -us -uc -j"$(nproc)" |
| 81 | + |
| 82 | +# .deb files are placed in the parent directory |
| 83 | +PARENT_DIR="$(dirname "$PROJECT_DIR")" |
| 84 | + |
| 85 | +DEB_MAIN="" |
| 86 | +DEB_LIB="" |
| 87 | +DEB_DEV="" |
| 88 | +for f in "$PARENT_DIR"/shadowsocks-libev_*.deb; do |
| 89 | + [ -f "$f" ] && DEB_MAIN="$f" && break |
| 90 | +done |
| 91 | +for f in "$PARENT_DIR"/libshadowsocks-libev2_*.deb; do |
| 92 | + [ -f "$f" ] && DEB_LIB="$f" && break |
| 93 | +done |
| 94 | +for f in "$PARENT_DIR"/libshadowsocks-libev-dev_*.deb; do |
| 95 | + [ -f "$f" ] && DEB_DEV="$f" && break |
| 96 | +done |
| 97 | + |
| 98 | +# --- phase 2: verify contents ---------------------------------------------- |
| 99 | + |
| 100 | +log "Phase 2: Verify package contents" |
| 101 | + |
| 102 | +# Check all three .deb files exist |
| 103 | +if [ -n "$DEB_MAIN" ] && [ -f "$DEB_MAIN" ]; then |
| 104 | + check_pass "shadowsocks-libev .deb exists: $(basename "$DEB_MAIN")" |
| 105 | +else |
| 106 | + check_fail "shadowsocks-libev .deb not found" |
| 107 | +fi |
| 108 | + |
| 109 | +if [ -n "$DEB_LIB" ] && [ -f "$DEB_LIB" ]; then |
| 110 | + check_pass "libshadowsocks-libev2 .deb exists: $(basename "$DEB_LIB")" |
| 111 | +else |
| 112 | + check_fail "libshadowsocks-libev2 .deb not found" |
| 113 | +fi |
| 114 | + |
| 115 | +if [ -n "$DEB_DEV" ] && [ -f "$DEB_DEV" ]; then |
| 116 | + check_pass "libshadowsocks-libev-dev .deb exists: $(basename "$DEB_DEV")" |
| 117 | +else |
| 118 | + check_fail "libshadowsocks-libev-dev .deb not found" |
| 119 | +fi |
| 120 | + |
| 121 | +# Bail early if any .deb is missing - remaining checks would all fail |
| 122 | +if [ "$FAIL_COUNT" -gt 0 ]; then |
| 123 | + summary |
| 124 | +fi |
| 125 | + |
| 126 | +# Main package: binaries |
| 127 | +for bin in ss-local ss-server ss-redir ss-tunnel ss-manager; do |
| 128 | + check_file_in_deb "$DEB_MAIN" "usr/bin/${bin}" "$bin binary in main package" |
| 129 | +done |
| 130 | + |
| 131 | +# Main package: man pages |
| 132 | +for bin in ss-local ss-server ss-redir ss-tunnel ss-manager; do |
| 133 | + check_file_in_deb "$DEB_MAIN" "usr/share/man/man1/$bin\\.1" "$bin man page in main package" |
| 134 | +done |
| 135 | + |
| 136 | +# Shared library package |
| 137 | +check_file_in_deb "$DEB_LIB" "usr/lib/.*/libshadowsocks-libev\\.so\\." "shared library in lib package" |
| 138 | + |
| 139 | +# Dev package: header |
| 140 | +check_file_in_deb "$DEB_DEV" "usr/include/shadowsocks\\.h" "shadowsocks.h header in dev package" |
| 141 | + |
| 142 | +# Dev package: pkg-config |
| 143 | +check_file_in_deb "$DEB_DEV" "usr/lib/.*/pkgconfig/shadowsocks-libev\\.pc" "pkg-config file in dev package" |
| 144 | + |
| 145 | +# Dev package: unversioned .so symlink |
| 146 | +check_file_in_deb "$DEB_DEV" "usr/lib/.*/libshadowsocks-libev\\.so[^.]" "unversioned .so symlink in dev package" |
| 147 | + |
| 148 | +# --- phase 3: install ------------------------------------------------------- |
| 149 | + |
| 150 | +log "Phase 3: Install packages" |
| 151 | + |
| 152 | +sudo dpkg -i "$DEB_LIB" "$DEB_DEV" "$DEB_MAIN" || true |
| 153 | +sudo apt-get -f install -y |
| 154 | + |
| 155 | +# Verify dpkg thinks they are installed |
| 156 | +for pkg in shadowsocks-libev libshadowsocks-libev2 libshadowsocks-libev-dev; do |
| 157 | + if dpkg -s "$pkg" >/dev/null 2>&1; then |
| 158 | + check_pass "$pkg installed" |
| 159 | + else |
| 160 | + check_fail "$pkg not installed" |
| 161 | + fi |
| 162 | +done |
| 163 | + |
| 164 | +# --- phase 4: smoke-test ---------------------------------------------------- |
| 165 | + |
| 166 | +log "Phase 4: Smoke-test installed binaries" |
| 167 | + |
| 168 | +# Each binary should respond to --help |
| 169 | +for bin in ss-local ss-server ss-redir ss-tunnel ss-manager; do |
| 170 | + check_command "$bin --help" "$bin --help runs" |
| 171 | +done |
| 172 | + |
| 173 | +# Shared library should be findable by ldconfig |
| 174 | +sudo ldconfig |
| 175 | +if ldconfig -p | grep -q libshadowsocks-libev; then |
| 176 | + check_pass "libshadowsocks-libev found by ldconfig" |
| 177 | +else |
| 178 | + check_fail "libshadowsocks-libev not found by ldconfig" |
| 179 | +fi |
| 180 | + |
| 181 | +# Header should be in the include path |
| 182 | +if [ -f /usr/include/shadowsocks.h ]; then |
| 183 | + check_pass "shadowsocks.h installed in /usr/include" |
| 184 | +else |
| 185 | + check_fail "shadowsocks.h not installed in /usr/include" |
| 186 | +fi |
| 187 | + |
| 188 | +# --- summary ---------------------------------------------------------------- |
| 189 | + |
| 190 | +summary |
0 commit comments