|
5 | 5 | archive_tar "archive/tar" |
6 | 6 | "bytes" |
7 | 7 | "context" |
| 8 | + stderrors "errors" |
8 | 9 | "fmt" |
9 | 10 | "io" |
10 | 11 | "net/http" |
@@ -487,6 +488,41 @@ func TestExtractZstdDrainsBufferedReaderToEOF(t *testing.T) { |
487 | 488 | }) |
488 | 489 | } |
489 | 490 |
|
| 491 | +// ─── Truncated archive test ────────────────────────────────────────────────── |
| 492 | + |
| 493 | +// TestExtractBundleTruncatedArchive verifies that extractBundleZstd returns an |
| 494 | +// io.ErrUnexpectedEOF when the archive is truncated, so the caller can warn |
| 495 | +// instead of fatally erroring out. |
| 496 | +func TestExtractBundleTruncatedArchive(t *testing.T) { |
| 497 | + ctx := context.Background() |
| 498 | + srcDir := t.TempDir() |
| 499 | + |
| 500 | + // Create two files so we can truncate mid-archive. |
| 501 | + must(t, os.MkdirAll(filepath.Join(srcDir, "caches"), 0o755)) |
| 502 | + must(t, os.WriteFile(filepath.Join(srcDir, "caches", "first.jar"), bytes.Repeat([]byte("A"), 4096), 0o644)) |
| 503 | + must(t, os.WriteFile(filepath.Join(srcDir, "caches", "second.jar"), bytes.Repeat([]byte("B"), 4096), 0o644)) |
| 504 | + |
| 505 | + var archive bytes.Buffer |
| 506 | + must(t, CreateDeltaTarZstd(ctx, &archive, srcDir, []string{"caches/first.jar", "caches/second.jar"})) |
| 507 | + |
| 508 | + // Truncate the compressed archive at roughly 60% to simulate a partial upload. |
| 509 | + truncated := archive.Bytes()[:archive.Len()*60/100] |
| 510 | + |
| 511 | + gradleHome := t.TempDir() |
| 512 | + projectDir := t.TempDir() |
| 513 | + |
| 514 | + _, err := extractBundleZstd(ctx, bytes.NewReader(truncated), []extractRule{ |
| 515 | + {prefix: "caches/", baseDir: gradleHome}, |
| 516 | + }, projectDir, false) |
| 517 | + |
| 518 | + if err == nil { |
| 519 | + t.Fatal("expected an error from truncated archive, got nil") |
| 520 | + } |
| 521 | + if !stderrors.Is(err, io.ErrUnexpectedEOF) { |
| 522 | + t.Fatalf("expected io.ErrUnexpectedEOF in error chain, got: %v", err) |
| 523 | + } |
| 524 | +} |
| 525 | + |
490 | 526 | // ─── Round-trip archive test ───────────────────────────────────────────────── |
491 | 527 |
|
492 | 528 | // TestTarZstdRoundTrip verifies that CreateTarZstd → extractTarZstd preserves |
|
0 commit comments