name: "End to End" on: push: branches: [ master ] pull_request: branches: [ master ] concurrency: group: ${{ github.head_ref }}/e2e cancel-in-progress: true permissions: contents: read defaults: run: working-directory: docker jobs: e2e: name: FUSE Mount runs-on: ubuntu-22.04 timeout-minutes: 30 steps: - name: Set up Go 1.x uses: actions/setup-go@8e57b58e57be52ac95949151e2777ffda8501267 # v2 with: go-version: ^1.13 id: go - name: Check out code into the Go module directory uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Cache Docker layers uses: actions/cache@v4 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-e2e-${{ github.sha }} restore-keys: | ${{ runner.os }}-buildx-e2e- - name: Install dependencies run: | # Use faster mirrors and install with timeout echo "deb http://azure.archive.ubuntu.com/ubuntu/ $(lsb_release -cs) main restricted universe multiverse" | sudo tee /etc/apt/sources.list echo "deb http://azure.archive.ubuntu.com/ubuntu/ $(lsb_release -cs)-updates main restricted universe multiverse" | sudo tee -a /etc/apt/sources.list sudo apt-get update --fix-missing sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends fuse # Verify FUSE installation echo "FUSE version: $(fusermount --version 2>&1 || echo 'fusermount not found')" echo "FUSE device: $(ls -la /dev/fuse 2>&1 || echo '/dev/fuse not found')" - name: Start SeaweedFS timeout-minutes: 10 run: | # Enable Docker buildkit for better caching export DOCKER_BUILDKIT=1 export COMPOSE_DOCKER_CLI_BUILD=1 # Build with retry logic for i in {1..3}; do echo "Build attempt $i/3" if make build_e2e; then echo "Build successful on attempt $i" break elif [ $i -eq 3 ]; then echo "Build failed after 3 attempts" exit 1 else echo "Build attempt $i failed, retrying in 30 seconds..." sleep 30 fi done # Start services with wait docker compose -f ./compose/e2e-mount.yml up --wait - name: Run FIO 4k timeout-minutes: 15 run: | echo "Starting FIO at: $(date)" # Concurrent r/w echo 'Run randrw with size=16M bs=4k' docker compose -f ./compose/e2e-mount.yml exec mount timeout -k5 60 fio --name=fiotest --filename=/mnt/seaweedfs/fiotest --size=16M --rw=randrw --bs=4k --direct=1 --numjobs=8 --ioengine=libaio --group_reporting --runtime=30 --time_based=1 echo "Verify FIO at: $(date)" # Verified write echo 'Run randwrite with size=16M bs=4k' docker compose -f ./compose/e2e-mount.yml exec mount timeout -k5 60 fio --name=fiotest --filename=/mnt/seaweedfs/fiotest --size=16M --rw=randwrite --bs=4k --direct=1 --numjobs=8 --ioengine=libaio --iodepth=32 --group_reporting --runtime=30 --time_based=1 --do_verify=0 --verify=crc32c --verify_backlog=1 - name: Run FIO 128k timeout-minutes: 15 run: | echo "Starting FIO at: $(date)" # Concurrent r/w echo 'Run randrw with size=16M bs=128k' docker compose -f ./compose/e2e-mount.yml exec mount timeout -k5 60 fio --name=fiotest --filename=/mnt/seaweedfs/fiotest --size=16M --rw=randrw --bs=128k --direct=1 --numjobs=8 --ioengine=libaio --iodepth=32 --group_reporting --runtime=30 --time_based=1 echo "Verify FIO at: $(date)" # Verified write echo 'Run randwrite with size=16M bs=128k' docker compose -f ./compose/e2e-mount.yml exec mount timeout -k5 60 fio --name=fiotest --filename=/mnt/seaweedfs/fiotest --size=16M --rw=randwrite --bs=128k --direct=1 --numjobs=8 --ioengine=libaio --iodepth=32 --group_reporting --runtime=30 --time_based=1 --do_verify=0 --verify=crc32c --verify_backlog=1 - name: Run FIO 1MB timeout-minutes: 15 run: | echo "Starting FIO at: $(date)" # Concurrent r/w echo 'Run randrw with size=16M bs=1m' docker compose -f ./compose/e2e-mount.yml exec mount timeout -k5 60 fio --name=fiotest --filename=/mnt/seaweedfs/fiotest --size=16M --rw=randrw --bs=1m --direct=1 --numjobs=8 --ioengine=libaio --iodepth=32 --group_reporting --runtime=30 --time_based=1 echo "Verify FIO at: $(date)" # Verified write echo 'Run randwrite with size=16M bs=1m' docker compose -f ./compose/e2e-mount.yml exec mount timeout -k5 60 fio --name=fiotest --filename=/mnt/seaweedfs/fiotest --size=16M --rw=randwrite --bs=1m --direct=1 --numjobs=8 --ioengine=libaio --iodepth=32 --group_reporting --runtime=30 --time_based=1 --do_verify=0 --verify=crc32c --verify_backlog=1 - name: Save logs if: always() run: | docker compose -f ./compose/e2e-mount.yml logs > output.log echo 'Showing last 500 log lines of mount service:' docker compose -f ./compose/e2e-mount.yml logs --tail 500 mount - name: Check for data races if: always() continue-on-error: true # TODO: remove this comment to enable build failure on data races (after all are fixed) run: grep -A50 'DATA RACE' output.log && exit 1 || exit 0 - name: Archive logs if: always() uses: actions/upload-artifact@v4 with: name: output-logs path: docker/output.log - name: Cleanup if: always() run: docker compose -f ./compose/e2e-mount.yml down --volumes --remove-orphans --rmi all