Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1317,10 +1317,16 @@ jobs:

- name: Unpack the e2e binaries
shell: bash
# Decompress to a file, not into `| tar -xf -`: a tar that exits at
# the end-of-archive marker without draining stdin (macOS's does)
# leaves zstd writing into a closed pipe, and pipefail turns its
# "Broken pipe" into a failed leg that evicts the queue entry.
run: |
set -euo pipefail
mkdir -p target/e2e-bin
zstd -q -d -c target/e2e-archive/e2e-bin.tar.zst | tar -xf - -C target/e2e-bin
zstd -q -d -f target/e2e-archive/e2e-bin.tar.zst -o target/e2e-bin.tar
tar -xf target/e2e-bin.tar -C target/e2e-bin
rm target/e2e-bin.tar

- name: Stage the CLI where the test binaries expect it
# `CARGO_BIN_EXE_socket-patch` was baked in at compile time as
Expand Down Expand Up @@ -2165,10 +2171,16 @@ jobs:
path: target/e2e-archive
- name: Unpack the e2e binaries
shell: bash
# Decompress to a file, not into `| tar -xf -`: a tar that exits at
# the end-of-archive marker without draining stdin (macOS's does)
# leaves zstd writing into a closed pipe, and pipefail turns its
# "Broken pipe" into a failed leg that evicts the queue entry.
run: |
set -euo pipefail
mkdir -p target/e2e-bin
zstd -q -d -c target/e2e-archive/e2e-bin.tar.zst | tar -xf - -C target/e2e-bin
zstd -q -d -f target/e2e-archive/e2e-bin.tar.zst -o target/e2e-bin.tar
tar -xf target/e2e-bin.tar -C target/e2e-bin
rm target/e2e-bin.tar
- name: Install Rust
run: rustup show
- name: Install the cargo under test
Expand Down
24 changes: 24 additions & 0 deletions scripts/tests/test_ci_e2e_archive.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
"""Run CI's real archive commands and check binary/permission round trips."""

import importlib.util
import io
import os
from pathlib import Path
import re
import shutil
import stat
import subprocess
import tarfile
import tempfile
import textwrap
import unittest
Expand Down Expand Up @@ -86,6 +88,28 @@ def test_missing_bundle_fails_even_when_compressor_accepts_empty_input(self):
(work / "target").mkdir()
self.assertNotEqual(run(compressor, work).returncode, 0)

def test_consumer_survives_a_tar_that_stops_at_the_end_marker(self):
# Some tars (macOS's; GNU tar too) exit at the end-of-archive marker
# without reading the rest of stdin. Bytes after the marker made a
# `zstd -d -c | tar -xf -` consumer fail with "Broken pipe".
payload = b"\x7fELF\x00cli fixture\xff"
for consumer in commands("Unpack the e2e binaries"):
with tempfile.TemporaryDirectory(prefix="e2e-trailing-") as directory:
work = Path(directory)
tar = work / "bundle.tar"
with tarfile.open(tar, "w") as bundle:
info = tarfile.TarInfo("socket-patch")
info.size, info.mode = len(payload), 0o755
bundle.addfile(info, io.BytesIO(payload))
with tar.open("ab") as f:
f.write(bytes(2 * 1024 * 1024))
archive_dir = work / "target/e2e-archive"
archive_dir.mkdir(parents=True)
subprocess.run(["zstd", "-q", str(tar), "-o", str(archive_dir / "e2e-bin.tar.zst")], check=True)
result = run(consumer, work)
self.assertEqual(result.returncode, 0, result.stderr)
self.assertEqual((work / "target/e2e-bin/socket-patch").read_bytes(), payload)

def test_corrupt_archive_fails_the_consumer_step(self):
for consumer in commands("Unpack the e2e binaries"):
with tempfile.TemporaryDirectory(prefix="e2e-bad-archive-") as directory:
Expand Down
Loading