Skip to content

refactor(storage): consolidate IO reader wrappers#2570

Draft
levb wants to merge 228 commits intomainfrom
lev-storage-rationalize
Draft

refactor(storage): consolidate IO reader wrappers#2570
levb wants to merge 228 commits intomainfrom
lev-storage-rationalize

Conversation

@levb
Copy link
Copy Markdown
Contributor

@levb levb commented May 5, 2026

Unify the scattered io.ReadCloser wrapper types into a single
io_wrappers.go file with interface assertions as a TOC:
offsetReader, instrumentedReader, cancelReader, sectionReader.

Pre-cursor to #2431, taking all non-functional refactoring into a separate PR

levb and others added 30 commits February 27, 2026 05:52
…ning

- Use header.HugepageSize for uncompressed fetch alignment (semantically correct)
- Stream NFS cache hits directly into ReadFrame instead of buffering in memory
- Fix timer placement to cover full GetFrame (read + decompression)
- Fix onRead callback: nil for compressed inner calls (prevents double-invoke),
  pass through for uncompressed (bytes are final)
- Remove panic recovery from runFetch (never in main)
- Remove low-value chunker tests subsumed by ConcurrentStress
- Remove 4MB frame configs from benchmarks (targeting 2MB only)
- Remove unused readCacheFile function

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ble NFS cache

- Remove dead flagsClient chain through chunker/build/template layers (~15 files)
- Delete ChunkerConfigFlag (unused after flagsClient removal)
- Delete mock_flagsclient_test.go
- Simplify GetUploadOptions: remove redundant intOr/strOr fallbacks (flags have defaults)
- Add GetCompressionType helper to frame_table.go, deduplicate compression type extraction
- Replace [16]byte{} with uuid.Nil and "rootfs.ext4" with storage.RootfsName in inspect-build
- Simplify UploadV4Header return pattern
- Remove onRead callback from legacy fullFetchChunker (FullFetch should not use progressive reads)
- Re-enable NFS cache in template cache.go
- Remove all fmt.Printf debug instrumentation from orchestrator

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…sionType threading

Add per-build file size and SHA-256 checksum to V4 headers, eliminating
the redundant Size() network call when opening upstream data files on
the read path. Checksums are computed for free by piggybacking on
CompressStream's existing frame iteration.

Remove the separate compressionType parameter threaded through
getBuild → newStorageDiff → NewChunker; the read path now derives
compression state from the per-mapping FrameTable directly.

V4 binary format change (not yet deployed):
  [Metadata] [LZ4: numBuilds, builds(uuid+size+checksum),
              numMappings, mappings...]

V3 path unchanged — falls back to Size() call when size is unknown.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Merge writeFrameToCache and writeChunkToCache into unified writeToCache
  with lock + atomic rename, used by all three cache write paths
- Fix file descriptor leak in cache hit paths: defer f.Close() and wrap
  in NopCloser so ReadFrame's close doesn't double-close the fd
- Add defer uploader.Close() in CompressStream so PartUploader file
  handles are released on error paths between Start() and Complete()
- Make Close() idempotent via sync.Once on fsPartUploader and filePartWriter

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The SHA-256 checksum in BuildFileInfo now covers uncompressed data,
making it useful for end-to-end integrity verification of the original
content. Updated inspect-build to use SHA-256 (replacing MD5) and
verify checksums against the header. Fixed early-return lint warnings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
GetUploadOptions now accepts fileType and useCase parameters, enriching
the LD evaluation context so dashboard targeting rules can differentiate
(e.g. compress memfile but not rootfs, or builds but not pauses).
TemplateBuild accepts per-file opts directly instead of holding an ff
reference.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Progressive path: write compressed chunks to NFS via AtomicImmutableFile
concurrently with decompression instead of waiting until after it
completes. Simple path: remove unnecessary copy in cacheFrameAsync since
compressedBuf is allocated fresh per call and never modified after.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
levb and others added 23 commits April 21, 2026 12:28
- block: lock fetchSession.advance so bytesReady.Store + cond.Broadcast
  happen under s.mu, closing a wait/broadcast race where waiters could
  miss a wakeup after observing stale bytesReady.

- storage/compress: clamp maxUploadConcurrency to >=1 in compressStream
  (errgroup SetLimit(n+1) with n=0 leaves only the read-loop slot,
  deadlocking uploaders) and clamp cfg.FrameEncodeWorkers to >=1 in
  readLoop (per-part errgroup with SetLimit(0) rejects all Go() calls
  and hangs addFrame). Default COMPRESS_FRAME_ENCODE_WORKERS is 0, so
  this is a real deadlock path.

- storage/compress: drop CompressBytes concurrency from 4 to 1.
  It's a test helper over an in-memory uploader — parallelism there
  adds nothing and invites questions.

- storage/header: consolidate the two local `const = 4` declarations
  in serializeV4 / deserializeV4 into a single package-level
  v4SizePrefixLen at the top of serialization_v4.go.
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Nil-safe FrameTable size accessors; strip compression suffix in peerserver
LookupDiff; thread putOpts.Metadata through compressed GCS upload; defer
fs sidecar write until after compressStream; revert toothless NotNil tests.
Mirrors V4's collectAncestorBuilds gate so layered V3 builds can't make
their hash→BuildID lookup globally visible before ancestor data files
land in storage. Restores the invariant the deleted UploadTracker held.
- peerserver/seekable + localDiff: use logical cache.Size(), not
  on-disk FileSize() (8x-inflated formula broke V3/V4 P2P resume).
- storage_google.StoreFile: one outer WriteFromFileSystem timer
  covering all branches; drop the shadowed OneShot; tag with
  compression.type/level.
- Privatize ResolveCompressConfig into sandbox; validate frame size
  against the real per-file block size from the snapshot diff header.
- CI: add lz4 matrix; propagate COMPRESS_* to the base-template
  build via .env.test so the fixture matches the services.
Unify the scattered io.ReadCloser wrapper types into a single
io_wrappers.go file with interface assertions as a TOC:
offsetReader, instrumentedReader, cancelReader, sectionReader.
@codecov
Copy link
Copy Markdown

codecov Bot commented May 5, 2026

❌ 9 Tests Failed:

Tests completed Failed Passed Skipped
2570 9 2561 7
View the full list of 11 ❄️ flaky test(s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/metrics::TestTeamMetrics

Flake rate in main: 50.00% (Passed 9 times, Failed 9 times)

Stack Traces | 2.02s run time
=== RUN   TestTeamMetrics
=== PAUSE TestTeamMetrics
=== CONT  TestTeamMetrics
    team_metrics_test.go:61: 
        	Error Trace:	.../api/metrics/team_metrics_test.go:61
        	Error:      	Should be true
        	Test:       	TestTeamMetrics
        	Messages:   	MaxConcurrentSandboxes should be >= 0
--- FAIL: TestTeamMetrics (2.02s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/sandboxes::TestSnapshotTemplateCreateSandbox

Flake rate in main: 12.50% (Passed 7 times, Failed 1 times)

Stack Traces | 0s run time
=== RUN   TestSnapshotTemplateCreateSandbox
=== PAUSE TestSnapshotTemplateCreateSandbox
=== CONT  TestSnapshotTemplateCreateSandbox
--- FAIL: TestSnapshotTemplateCreateSandbox (0.00s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/sandboxes::TestSnapshotTemplateCreateSandbox/create_sandbox_from_named_snapshot_using_name

Flake rate in main: 12.50% (Passed 7 times, Failed 1 times)

Stack Traces | 18s run time
=== RUN   TestSnapshotTemplateCreateSandbox/create_sandbox_from_named_snapshot_using_name
=== PAUSE TestSnapshotTemplateCreateSandbox/create_sandbox_from_named_snapshot_using_name
=== CONT  TestSnapshotTemplateCreateSandbox/create_sandbox_from_named_snapshot_using_name
    snapshot_template_test.go:250: 
        	Error Trace:	.../api/sandboxes/snapshot_template_test.go:37
        	            				.../api/sandboxes/snapshot_template_test.go:250
        	Error:      	Not equal: 
        	            	expected: 201
        	            	actual  : 500
        	Test:       	TestSnapshotTemplateCreateSandbox/create_sandbox_from_named_snapshot_using_name
--- FAIL: TestSnapshotTemplateCreateSandbox/create_sandbox_from_named_snapshot_using_name (18.02s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/sandboxes::TestUpdateNetworkConfig

Flake rate in main: 56.00% (Passed 11 times, Failed 14 times)

Stack Traces | 39.5s run time
=== RUN   TestUpdateNetworkConfig
=== PAUSE TestUpdateNetworkConfig
=== CONT  TestUpdateNetworkConfig
--- FAIL: TestUpdateNetworkConfig (39.51s)
github.com/e2b-dev/infra/tests/integration/internal/tests/api/sandboxes::TestUpdateNetworkConfig/pause_resume_preserves_allow_internet_access_false

Flake rate in main: 50.00% (Passed 11 times, Failed 11 times)

Stack Traces | 3.14s run time
=== RUN   TestUpdateNetworkConfig/pause_resume_preserves_allow_internet_access_false
Executing command curl in sandbox iyfmdvey9zwoqtcv4gdj0
    sandbox_network_update_test.go:372: Command [curl] output: event:{start:{pid:1352}}
    sandbox_network_update_test.go:372: Command [curl] output: event:{end:{exit_code:35 exited:true status:"exit status 35" error:"exit status 35"}}
Executing command curl in sandbox iyfmdvey9zwoqtcv4gdj0
    sandbox_network_update_test.go:372: Command [curl] output: event:{start:{pid:1353}}
    sandbox_network_update_test.go:372: Command [curl] output: event:{end:{exit_code:35 exited:true status:"exit status 35" error:"exit status 35"}}
Executing command curl in sandbox iyfmdvey9zwoqtcv4gdj0
    sandbox_network_update_test.go:391: Command [curl] output: event:{start:{pid:1355}}
    sandbox_network_update_test.go:391: Command [curl] output: event:{data:{stdout:"HTTP/2 302 \r\nx-content-type-options: nosniff\r\nlocation: https://dns.google/\r\ndate: Tue, 05 May 2026 18:25:29 GMT\r\ncontent-type: text/html; charset=UTF-8\r\nserver: HTTP server (unknown)\r\ncontent-length: 216\r\nx-xss-protection: 0\r\nx-frame-options: SAMEORIGIN\r\nalt-svc: h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000\r\n\r\n"}}
    sandbox_network_update_test.go:391: Command [curl] output: event:{end:{exited:true status:"exit status 0"}}
    sandbox_network_update_test.go:391: Command [curl] completed successfully in sandbox iyfmdvey9zwoqtcv4gdj0
    sandbox_network_update_test.go:391: 
        	Error Trace:	.../api/sandboxes/sandbox_network_out_test.go:74
        	            				.../api/sandboxes/sandbox_network_update_test.go:60
        	            				.../api/sandboxes/sandbox_network_update_test.go:391
        	Error:      	An error is expected but got nil.
        	Test:       	TestUpdateNetworkConfig/pause_resume_preserves_allow_internet_access_false
        	Messages:   	https://8.8.8.8 should be blocked
--- FAIL: TestUpdateNetworkConfig/pause_resume_preserves_allow_internet_access_false (3.14s)
github.com/e2b-dev/infra/tests/integration/internal/tests/envd::TestBindLocalhost

Flake rate in main: 12.50% (Passed 7 times, Failed 1 times)

Stack Traces | 0s run time
=== RUN   TestBindLocalhost
=== PAUSE TestBindLocalhost
=== CONT  TestBindLocalhost
--- FAIL: TestBindLocalhost (0.00s)
github.com/e2b-dev/infra/tests/integration/internal/tests/envd::TestBindLocalhost/bind_0_0_0_0

Flake rate in main: 12.50% (Passed 7 times, Failed 1 times)

Stack Traces | 7.05s run time
=== RUN   TestBindLocalhost/bind_0_0_0_0
=== PAUSE TestBindLocalhost/bind_0_0_0_0
=== CONT  TestBindLocalhost/bind_0_0_0_0
    localhost_bind_test.go:69: Command [python] output: event:{start:{pid:1265}}
Executing command python in sandbox i81nvtzmfl8tfntgnj951
    localhost_bind_test.go:90: 
        	Error Trace:	.../tests/envd/localhost_bind_test.go:90
        	Error:      	Not equal: 
        	            	expected: 200
        	            	actual  : 502
        	Test:       	TestBindLocalhost/bind_0_0_0_0
        	Messages:   	Unexpected status code 502 for bind address 0.0.0.0
--- FAIL: TestBindLocalhost/bind_0_0_0_0 (7.05s)
github.com/e2b-dev/infra/tests/integration/internal/tests/envd::TestBindLocalhost/bind_localhost

Flake rate in main: 12.50% (Passed 7 times, Failed 1 times)

Stack Traces | 7.61s run time
=== RUN   TestBindLocalhost/bind_localhost
=== PAUSE TestBindLocalhost/bind_localhost
=== CONT  TestBindLocalhost/bind_localhost
    localhost_bind_test.go:69: Command [python] output: event:{start:{pid:1266}}
Executing command python in sandbox imh1cu5t7cm9n7wg9ahc3
    localhost_bind_test.go:90: 
        	Error Trace:	.../tests/envd/localhost_bind_test.go:90
        	Error:      	Not equal: 
        	            	expected: 200
        	            	actual  : 502
        	Test:       	TestBindLocalhost/bind_localhost
        	Messages:   	Unexpected status code 502 for bind address localhost
--- FAIL: TestBindLocalhost/bind_localhost (7.61s)
github.com/e2b-dev/infra/tests/integration/internal/tests/orchestrator::TestSandboxMemoryIntegrity

Flake rate in main: 12.50% (Passed 7 times, Failed 1 times)

Stack Traces | 0s run time
=== RUN   TestSandboxMemoryIntegrity
=== PAUSE TestSandboxMemoryIntegrity
=== CONT  TestSandboxMemoryIntegrity
--- FAIL: TestSandboxMemoryIntegrity (0.00s)
github.com/e2b-dev/infra/tests/integration/internal/tests/orchestrator::TestSandboxMemoryIntegrity/stress-ng_verify

Flake rate in main: 12.50% (Passed 7 times, Failed 1 times)

Stack Traces | 31.6s run time
=== RUN   TestSandboxMemoryIntegrity/stress-ng_verify
=== PAUSE TestSandboxMemoryIntegrity/stress-ng_verify
=== CONT  TestSandboxMemoryIntegrity/stress-ng_verify
Executing command bash in sandbox imw8tz2fo3dykbtlz5ubr (user: root)
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{start:{pid:1265}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Hit:1 http://deb.debian.org/debian bookworm InRelease\nHit:2 http://deb.debian.org/debian bookworm-updates InRelease\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Hit:3 http://deb.debian.org/debian-security bookworm-security InRelease\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Reading package lists..."}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Reading package lists..."}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Building dependency tree..."}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"\nReading state information..."}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"The following additional packages will be installed:\n  libdrm-common libdrm2 libegl-mesa0 libegl1 libgbm1 libglapi-mesa libgles2\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"  libglvnd0 libipsec-mb1 libjudydebian1 libsctp1 libwayland-client0\n  libwayland-server0 libx11-xcb1 libxcb-dri2-0 libxcb-dri3-0 libxcb-present0\n  libxcb-randr0 libxcb-sync1 libxcb-xfixes0 libxshmfence1\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Suggested packages:\n  lksctp-tools\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"The following NEW packages will be installed:\n  libdrm-common libdrm2 libegl-mesa0 libegl1 libgbm1 libglapi-mesa libgles2\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"  libglvnd0 libipsec-mb1 libjudydebian1 libsctp1 libwayland-client0\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"  libwayland-server0 libx11-xcb1 libxcb-dri2-0 libxcb-dri3-0 libxcb-present0\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"  libxcb-randr0 libxcb-sync1 libxcb-xfixes0 libxshmfence1 stress-ng time\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"0 upgraded, 23 newly installed, 0 to remove and 146 not upgraded.\nNeed to get 4781 kB of archives.\nAfter this operation, 25.6 MB of additional disk space will be used.\nGet:1 http://deb.debian.org/debian bookworm/main amd64 libdrm-common all 2.4.114-1 [7112 B]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:2 http://deb.debian.org/debian bookworm/main amd64 libdrm2 amd64 2.4.114-1+b1 [37.5 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:3 http://deb.debian.org/debian bookworm/main amd64 libwayland-server0 amd64 1.21.0-1 [35.9 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:4 http://deb.debian.org/debian bookworm/main amd64 libgbm1 amd64 22.3.6-1+deb12u1 [38.0 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:5 http://deb.debian.org/debian bookworm/main amd64 libglapi-mesa amd64 22.3.6-1+deb12u1 [35.7 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:6 http://deb.debian.org/debian bookworm/main amd64 libwayland-client0 amd64 1.21.0-1 [28.3 kB]\nGet:7 http://deb.debian.org/debian bookworm/main amd64 libx11-xcb1 amd64 2:1.8.4-2+deb12u2 [192 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:8 http://deb.debian.org/debian bookworm/main amd64 libxcb-dri2-0 amd64 1.15-1 [107 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:9 http://deb.debian.org/debian bookworm/main amd64 libxcb-dri3-0 amd64 1.15-1 [107 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:10 http://deb.debian.org/debian bookworm/main amd64 libxcb-present0 amd64 1.15-1 [105 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:11 http://deb.debian.org/debian bookworm/main amd64 libxcb-randr0 amd64 1.15-1 [117 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:12 http://deb.debian.org/debian bookworm/main amd64 libxcb-sync1 amd64 1.15-1 [109 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:13 http://deb.debian.org/debian bookworm/main amd64 libxcb-xfixes0 amd64 1.15-1 [109 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:14 http://deb.debian.org/debian bookworm/main amd64 libxshmfence1 amd64 1.3-1 [8820 B]\nGet:15 http://deb.debian.org/debian bookworm/main amd64 libegl-mesa0 amd64 22.3.6-1+deb12u1 [114 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:16 http://deb.debian.org/debian bookworm/main amd64 libglvnd0 amd64 1.6.0-1 [51.8 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:17 http://deb.debian.org/debian bookworm/main amd64 libgles2 amd64 1.6.0-1 [16.8 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:18 http://deb.debian.org/debian bookworm/main amd64 libipsec-mb1 amd64 1.3-2 [981 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:19 http://deb.debian.org/debian bookworm/main amd64 libjudydebian1 amd64 1.0.5-5+b2 [102 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:20 http://deb.debian.org/debian bookworm/main amd64 libsctp1 amd64 1.0.19+dfsg-2 [29.7 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:21 http://deb.debian.org/debian bookworm/main amd64 libegl1 amd64 1.6.0-1 [33.7 kB]\nGet:22 http://deb.debian.org/debian bookworm/main amd64 stress-ng amd64 0.15.06-2 [2363 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Get:23 http://deb.debian.org/debian bookworm/main amd64 time amd64 1.9-0.2 [50.8 kB]\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stderr:"debconf: delaying package configuration, since apt-utils is not installed\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Fetched 4781 kB in 1s (5990 kB/s)\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libdrm-common.\r\n(Reading database ... \r"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"(Reading database ... 5%\r(Reading database ... 10%\r(Reading database ... 15%\r(Reading database ... 20%\r(Reading database ... 25%\r(Reading database ... 30%\r(Reading database ... 35%\r(Reading database ... 40%\r(Reading database ... 45%\r(Reading database ... 50%\r(Reading database ... 55%\r(Reading database ... 60%\r(Reading database ... 65%\r"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"(Reading database ... 70%\r"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"(Reading database ... 75%\r"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"(Reading database ... 80%\r"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"(Reading database ... 85%\r"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"(Reading database ... 90%\r"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"(Reading database ... 95%\r"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"(Reading database ... 100%\r(Reading database ... 25971 files and directories currently installed.)\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../00-libdrm-common_2.4.114-1_all.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libdrm-common (2.4.114-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libdrm2:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../01-libdrm2_2.4.114-1+b1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libdrm2:amd64 (2.4.114-1+b1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libwayland-server0:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../02-libwayland-server0_1.21.0-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libwayland-server0:amd64 (1.21.0-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libgbm1:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../03-libgbm1_22.3.6-1+deb12u1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libgbm1:amd64 (22.3.6-1+deb12u1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libglapi-mesa:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../04-libglapi-mesa_22.3.6-1+deb12u1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libglapi-mesa:amd64 (22.3.6-1+deb12u1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libwayland-client0:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../05-libwayland-client0_1.21.0-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libwayland-client0:amd64 (1.21.0-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libx11-xcb1:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../06-libx11-xcb1_2%3a1.8.4-2+deb12u2_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libx11-xcb1:amd64 (2:1.8.4-2+deb12u2) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libxcb-dri2-0:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../07-libxcb-dri2-0_1.15-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libxcb-dri2-0:amd64 (1.15-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libxcb-dri3-0:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../08-libxcb-dri3-0_1.15-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libxcb-dri3-0:amd64 (1.15-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libxcb-present0:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../09-libxcb-present0_1.15-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libxcb-present0:amd64 (1.15-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libxcb-randr0:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../10-libxcb-randr0_1.15-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libxcb-randr0:amd64 (1.15-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libxcb-sync1:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../11-libxcb-sync1_1.15-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libxcb-sync1:amd64 (1.15-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libxcb-xfixes0:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../12-libxcb-xfixes0_1.15-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libxcb-xfixes0:amd64 (1.15-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libxshmfence1:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../13-libxshmfence1_1.3-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libxshmfence1:amd64 (1.3-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libegl-mesa0:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../14-libegl-mesa0_22.3.6-1+deb12u1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libegl-mesa0:amd64 (22.3.6-1+deb12u1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libglvnd0:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../15-libglvnd0_1.6.0-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libglvnd0:amd64 (1.6.0-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libgles2:amd64.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../16-libgles2_1.6.0-1_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libgles2:amd64 (1.6.0-1) ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package libipsec-mb1.\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Preparing to unpack .../17-libipsec-mb1_1.3-2_amd64.deb ...\r\n"}}
    sandbox_memory_integrity_test.go:141: Command [bash] output: event:{data:{stdout:"Unpacking libipsec-mb1 (1.3-2) ...\r\n"}}
    sandbox_memory_integrity_test.go:142: 
        	Error Trace:	.../tests/orchestrator/sandbox_memory_integrity_test.go:142
        	Error:      	Received unexpected error:
        	            	failed to execute command bash in sandbox imw8tz2fo3dykbtlz5ubr: invalid_argument: protocol error: incomplete envelope: unexpected EOF
        	Test:       	TestSandboxMemoryIntegrity/stress-ng_verify
--- FAIL: TestSandboxMemoryIntegrity/stress-ng_verify (31.61s)
github.com/e2b-dev/infra/tests/integration/internal/tests/orchestrator::TestSandboxMemoryIntegrity/tmpfs_hash

Flake rate in main: 12.50% (Passed 7 times, Failed 1 times)

Stack Traces | 30.7s run time
=== RUN   TestSandboxMemoryIntegrity/tmpfs_hash
=== PAUSE TestSandboxMemoryIntegrity/tmpfs_hash
=== CONT  TestSandboxMemoryIntegrity/tmpfs_hash
Executing command bash in sandbox i8n2m44nvj1b119d5tle3 (user: root)
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{start:{pid:1265}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"Hit:1 http://deb.debian.org/debian bookworm InRelease\nHit:2 http://deb.debian.org/debian bookworm-updates InRelease\nHit:3 http://deb.debian.org/debian-security bookworm-security InRelease\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"Reading package lists..."}}
Executing command bash in sandbox i53wiao3atwulgyy9r8ji (user: root)
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"Reading package lists..."}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"Building dependency tree..."}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"\nReading state information..."}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"The following NEW packages will be installed:\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"  time\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"0 upgraded, 1 newly installed, 0 to remove and 146 not upgraded.\nNeed to get 50.8 kB of archives.\nAfter this operation, 132 kB of additional disk space will be used.\nGet:1 http://deb.debian.org/debian bookworm/main amd64 time amd64 1.9-0.2 [50.8 kB]\n"}}
Executing command bash in sandbox ix0zfkeahdj8lem7lyt4b (user: root)
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stderr:"debconf: delaying package configuration, since apt-utils is not installed\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"Fetched 50.8 kB in 0s (416 kB/s)\n"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"Selecting previously unselected package time.\r\n(Reading database ... \r"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"(Reading database ... 5%\r(Reading database ... 10%\r(Reading database ... 15%\r(Reading database ... 20%\r(Reading database ... 25%\r(Reading database ... 30%\r(Reading database ... 35%\r(Reading database ... 40%\r(Reading database ... 45%\r"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"(Reading database ... 50%\r(Reading database ... 55%\r(Reading database ... 60%\r(Reading database ... 65%\r"}}
Executing command bash in sandbox ix0zfkeahdj8lem7lyt4b (user: root)
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"(Reading database ... 70%\r"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"(Reading database ... 75%\r"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"(Reading database ... 80%\r"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"(Reading database ... 85%\r"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"(Reading database ... 90%\r"}}
    sandbox_memory_integrity_test.go:33: Command [bash] output: event:{data:{stdout:"(Reading database ... 95%\r"}}
    sandbox_memory_integrity_test.go:34: 
        	Error Trace:	.../tests/orchestrator/sandbox_memory_integrity_test.go:34
        	Error:      	Received unexpected error:
        	            	failed to execute command bash in sandbox i8n2m44nvj1b119d5tle3: invalid_argument: protocol error: incomplete envelope: unexpected EOF
        	Test:       	TestSandboxMemoryIntegrity/tmpfs_hash
--- FAIL: TestSandboxMemoryIntegrity/tmpfs_hash (30.74s)

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

The error recording logic in the instrumented reader's Close method is mutually exclusive, which may cause read errors to be suppressed if a close error also occurs. A data race exists on the byte count and error fields because they are accessed concurrently by Read and Close without synchronization. Passing a nil error to the completion check in the cache writeback reader creates a regression that prevents the proper caching of short final chunks.

Comment thread packages/shared/pkg/storage/io_wrappers.go
Comment thread packages/shared/pkg/storage/io_wrappers.go
Comment thread packages/shared/pkg/storage/storage_cache_seekable.go
@tvi
Copy link
Copy Markdown
Contributor

tvi commented May 5, 2026

@cla-bot check

@cla-bot cla-bot Bot added the cla-signed label May 5, 2026
@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented May 5, 2026

The cla-bot has been summoned, and re-checked this pull request!

Base automatically changed from lev-compression-final to main May 5, 2026 20:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants