name: wolfSSH SFTP Test on: push: branches: [ 'master', 'main', 'release/**' ] pull_request: branches: [ '*' ] workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: create_matrix: runs-on: ubuntu-latest outputs: versions: ${{ steps.json.outputs.versions }} steps: - name: Create wolfSSL version matrix id: json run: | current=`curl -s https://api.github.com/repos/wolfssl/wolfssl/releases | grep tag_name | cut -d : -f 2,3 | tr -d \" | tr -d , | tr -d ' ' | head -1` last=`curl -s https://api.github.com/repos/wolfssl/wolfssl/releases | grep tag_name | cut -d : -f 2,3 | tr -d \" | tr -d , | tr -d ' ' | head -2 | tail -1` VERSIONS=$(echo "[ \"master\", \"$current\", \"$last\" ]") echo "wolfSSL versions found: $VERSIONS" echo "versions=$VERSIONS" >> $GITHUB_OUTPUT build_wolfssl: needs: create_matrix strategy: fail-fast: false matrix: os: [ ubuntu-latest ] wolfssl: ${{ fromJson(needs.create_matrix.outputs['versions']) }} name: Build wolfssl runs-on: ${{ matrix.os }} timeout-minutes: 4 steps: - name: Checking cache for wolfssl uses: actions/cache@v5 id: cache-wolfssl with: path: build-dir/ key: wolfssh-sftp-wolfssl-${{ matrix.wolfssl }}-${{ matrix.os }}-keygen lookup-only: true - name: Checkout, build, and install wolfssl if: steps.cache-wolfssl.outputs.cache-hit != 'true' uses: wolfSSL/actions-build-autotools-project@v1 with: repository: wolfssl/wolfssl ref: ${{ matrix.wolfssl }} path: wolfssl configure: --enable-ssh --enable-keygen check: false install: true build_wolfssh: needs: - build_wolfssl - create_matrix strategy: fail-fast: false matrix: os: [ ubuntu-latest ] wolfssl: ${{ fromJson(needs.create_matrix.outputs['versions']) }} name: Build and test wolfsftp runs-on: ${{ matrix.os }} timeout-minutes: 10 steps: - name: Checking cache for wolfssl uses: actions/cache@v5 with: path: build-dir/ key: wolfssh-sftp-wolfssl-${{ matrix.wolfssl }}-${{ matrix.os }}-keygen fail-on-cache-miss: true - uses: actions/checkout@v6 with: path: wolfssh/ - name: autogen working-directory: ./wolfssh/ run: ./autogen.sh - name: configure working-directory: ./wolfssh/ run : | ./configure --enable-sftp LDFLAGS="-L${{ github.workspace }}/build-dir/lib" CPPFLAGS="-I${{ github.workspace }}/build-dir/include -DWOLFSSH_NO_FPKI" - name: make working-directory: ./wolfssh/ run: make - name: Create test file run: | dd if=/dev/urandom of=/tmp/test.dat bs=1M count=2 echo "Created 2MB test file at /tmp/test.dat" md5sum /tmp/test.dat > /tmp/test.md5 - name: Start echoserver working-directory: ./wolfssh/ run: | ./examples/echoserver/echoserver -f & echo "Echoserver started with PID: $!" sleep 2 # Give the server time to start - name: Run SFTP test working-directory: ./wolfssh/ run: | # Create expect script to automate the SFTP client interaction cat > /tmp/sftp_test.exp << 'EOF' #!/usr/bin/expect -f set timeout 60 spawn ./examples/sftpclient/wolfsftp -N -h 127.0.0.1 -p 22222 -u jill expect "Password:" send "upthehill\r" expect "wolfSSH sftp>" send "put /tmp/test.dat test_received.dat\r" expect "wolfSSH sftp>" send "exit\r" expect eof EOF chmod +x /tmp/sftp_test.exp # Install expect sudo apt-get update && sudo apt-get install -y expect # Run the expect script /tmp/sftp_test.exp # Verify the files match (echoserver's CWD is ./wolfssh/) echo "Verifying file integrity..." if cmp -s /tmp/test.dat test_received.dat; then echo "SFTP Test PASSED: Files match" else echo "SFTP Test FAILED: Files do not match" exit 1 fi build_wolfssh_large_rw: needs: - build_wolfssl - create_matrix strategy: fail-fast: false matrix: os: [ ubuntu-latest ] wolfssl: ${{ fromJson(needs.create_matrix.outputs['versions']) }} name: Test wolfsftp large RW (10MB chunks, 3GB file) runs-on: ${{ matrix.os }} timeout-minutes: 20 steps: - name: Checking cache for wolfssl uses: actions/cache@v5 with: path: build-dir/ key: wolfssh-sftp-wolfssl-${{ matrix.wolfssl }}-${{ matrix.os }}-keygen fail-on-cache-miss: true - uses: actions/checkout@v6 with: path: wolfssh/ - name: autogen working-directory: ./wolfssh/ run: ./autogen.sh - name: configure working-directory: ./wolfssh/ run: | ./configure --enable-all \ LDFLAGS="-L${{ github.workspace }}/build-dir/lib" \ CPPFLAGS="-I${{ github.workspace }}/build-dir/include -DWOLFSSH_NO_SFTP_TIMEOUT -DWOLFSSH_MAX_SFTP_RW=10485760 -DWOLFSSH_MAX_CHN_NAMESZ=4200" - name: make working-directory: ./wolfssh/ run: make - name: Create 3GB test file working-directory: ./wolfssh/ run: | dd if=/dev/urandom of=seed.dat bs=1M count=10 for i in $(seq 1 308); do cat seed.dat >> large_test.dat; done rm seed.dat sha256sum large_test.dat > large_test.dat.sha256 echo "Created 3GB test file, SHA-256: $(cat large_test.dat.sha256)" - name: Start echoserver working-directory: ./wolfssh/ run: | ./examples/echoserver/echoserver -N -1 -R /tmp/echoserver_ready -d "$(pwd)" & echo $! > /tmp/echoserver.pid for i in $(seq 1 30); do [ -s /tmp/echoserver_ready ] && break sleep 0.2 done if [ ! -s /tmp/echoserver_ready ]; then echo "ERROR: echoserver failed to start" exit 1 fi echo "Echoserver ready on port $(cat /tmp/echoserver_ready)" - name: SFTP get 3GB file with 10MB chunk size working-directory: ./wolfssh/ run: | port=$(cat /tmp/echoserver_ready) ./examples/sftpclient/wolfsftp -N -u jill -P upthehill -p "$port" \ -G -l /tmp/large_test_copy.dat -r "$(pwd)/large_test.dat" - name: Verify file integrity working-directory: ./wolfssh/ run: | expected=$(awk '{print $1}' large_test.dat.sha256) actual=$(sha256sum /tmp/large_test_copy.dat | awk '{print $1}') echo "Expected SHA-256: $expected" echo "Actual SHA-256: $actual" if [ "$expected" != "$actual" ]; then echo "FAIL: SHA-256 mismatch" exit 1 fi echo "PASS: 3GB SFTP transfer with WOLFSSH_MAX_SFTP_RW=10485760 succeeded" - name: Stop echoserver if: always() run: kill "$(cat /tmp/echoserver.pid)" 2>/dev/null || true