Commit Graph
584 Commits
Author SHA1 Message Date
Nick Craig-Wood 05ac69e123 fstests: test uploads survive a transient HTTP error and return pooled buffers
Add an FsPutRetry integration test which uses the fshttp fault injector
to fail the first request carrying upload data, before it is sent, with
either a synthetic 500 or a connection reset, and then checks that Put
either succeeds with the correct contents or fails cleanly without
leaving a corrupt object behind.

It runs a single part upload and, for backends implementing
SetUploadChunkSizer, a chunked one. This catches backends which retry
an upload from a buffer which has already been consumed or returned to
the memory pool. Backends which don't use HTTP skip the test.

Also check in FsPutRetry and the large upload tests that the number of
buffers in use in the global memory pool is unchanged after an upload,
to catch backends which leak pooled buffers.
2026-09-01 14:21:52 +01:00
4722b94d1a sftp: implement multi-thread uploads - fixes #8185
The sftp backend could be used as the source of a multi-thread copy -
each chunk of a download is read on its own connection - but not as the
destination, because it did not implement OpenWriterAt. Uploading a
single large file was therefore limited to one connection while
downloading the same file was not, capping upload throughput well below
the link speed on high latency connections.

This implements OpenWriterAt for the sftp backend using lib/filepool. A
small pool of open write handles, each backed by its own connection,
lets the core write the chunks of a large file concurrently over several
connections. The file is created and truncated once up front so every
chunk offset is valid before the concurrent writes start.

Multi-thread uploads are off by default and turned on with the new
--sftp-multithread-upload flag, since many sftp servers only accept
sequential writes and would fail large uploads otherwise. Even when
enabled they fall back to a single connection when
--sftp-disable-concurrent-writes is set (a server that can't take
out-of-order packets on one handle won't take several handles either) or
when --sftp-connections caps the pool (the per-file fan-out would
otherwise deadlock waiting on it).

The OpenSSH test server (TestSFTPOpenssh) enables
--sftp-multithread-upload so the feature is exercised in CI against a
real server.

Tested against OpenSSH: a single large upload over a high latency link
went from ~12 MB/s to ~90 MB/s.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Splainte <r.wycke@hotmail.fr>
2026-08-30 13:06:06 +01:00
Nick Craig-Wood 4369d16a1c test_all: pikpak: ignore TestRcatSizeChecksum/Corrupted
Pikpak never returns MD5 for uploads which causes this test to fail.

Perhaps Pikpak should not declare MD5 but that is a bigger decision
being discussed in #9826
2026-08-26 12:00:22 +01:00
Nick Craig-Wood 237719bb8d build: modernize with "go fix -slicesbackward": use slices.Backward 2026-08-21 12:23:31 +01:00
Nick Craig-Wood 03f8582a55 fstests: check uploads terminate when the source ends before its declared size
A source reader which returns EOF before supplying as many bytes as it
declared should not cause a backend Put to hang, panic or create an
object claiming the declared size.

The layers above detect a truncated transfer by comparing sizes after
the upload, so a backend may either return an error or create a
shorter object.

See #9704
2026-08-03 20:58:14 +01:00
Nick Craig-Wood c81bc3aca2 test_all: mask internet archive tests which can't work 2026-07-27 12:25:22 +01:00
Nick Craig-Wood 2217d38273 test_all: run the Internet Archive tests with -short to speed them up
Every write operation waits for the server's processing tasks which
currently take minutes each, so the full test suite takes much longer
than the timeout. Running with -short skips the FsEncoding subtests
(which are already on the ignore list) and the chunked upload tests,
removing a large number of these waits.
2026-07-25 18:48:31 +01:00
Nick Craig-Wood b9009b1c13 test_all: use a fresh Internet Archive item for the integration tests
The old rclone-integration-test item has accumulated years of catalog
task churn and IA now deprioritises and periodically holds its tasks,
which makes the tests wait on the server's processing tasks for a
very long time. Start again with a fresh item (created with noindex
set so the test files stay out of IA's search index).
2026-07-21 10:28:47 +01:00
Nick Craig-Wood 4d6cc0ba1f test_all: ignore TestListDirSortedFn for linkbox
Linkbox can't upload files starting with . - the same reason
TestListDirSorted is already ignored.
2026-07-20 17:22:12 +01:00
Nick Craig-Wood 8ac8d1821c test_all: ignore TestRWFileHandleWriteNoWrite for imagekit
ImageKit can't store zero length files. The test only skips itself
when the failure is reported synchronously, but with --vfs-cache-mode
writes the writeback happens asynchronously and deliberately swallows
the error, so the test fails on the missing files. Other backends
which can't store empty files already ignore this test.
2026-07-17 18:29:39 +01:00
Nick Craig-Wood 0775b15ccf test_all: ignore TestSyncCompareDest for cloudinary
Cloudinary's search API which NewObject uses is eventually
consistent, so the --compare-dest lookup of a just uploaded file
misses it and the test fails. TestCopyFileCompareDest is already
ignored for the same reason.
2026-07-17 18:29:39 +01:00
Nick Craig-Wood 7dd42c93cf fstests: check backends return accurate object fingerprints after writes
Layers which wrap backends, such as the hasher backend and the VFS
cache, use fs.Fingerprint to detect whether an object has changed.
This only works if the object a backend hands back from a write
operation is identical to the object a fresh listing returns. If a
backend keeps the source's nanosecond precision modtime in memory
while the server stores milliseconds, or omits a hash the server
knows, every fingerprint comparison fails and cached hashes or files
are silently invalidated.

The existing tests compared modtimes within f.Precision() so they
could not detect these sub-precision divergences.

Add a checkFingerprint helper which asserts the fast and slow
fs.Fingerprint of the object returned from a write operation exactly
match those of the object read back from the remote, and wire it into
all the write paths which return or mutate an object: Put (all
variants), PutStream, large and streamed uploads, Update, SetModTime,
server side Copy and Move, and the metadata mutating Copy/Move
subtests.

Rework the ObjectOpenFingerprint test to use the same helper against
a fully read reference object, with subtests reporting which kind of
read is being checked.
2026-07-13 13:40:53 +01:00
Nick Craig-Wood d66235d556 fstests: check opening an object doesn't change its fingerprint
Add TestObjectOpenFingerprint which reads an object's fast and slow
fingerprints, then opens it in several ways - a full read, a seek read
and ranged reads - and after a refresh, checking the fingerprint never
changes.
2026-07-09 17:46:31 +01:00
jzunigax2andNick Craig-Wood 75429ca647 internxt: handle file size limit errors during uploads 2026-07-09 12:42:21 +01:00
Nick Craig-Wood 9c9fbebf7f serve s3: skip TestS3Minio when the docker test framework is unavailable
TestS3Minio brings up a minio container via the fstest/testserver
framework, which exec's bash init.d scripts that shell out to docker.
This is not available on all platforms - Windows has no POSIX shell to
run the scripts, and macOS CI runners have no docker daemon - which
caused the build to fail there.

Add testy.SkipUnlessDocker to detect whether the framework can run and
skip the test when it cannot.
2026-06-11 17:13:11 +01:00
Nick Craig-Wood acb6155654 test_all: skip bisync normalization tests on Dropbox
The bisync normalization test relies on uploading distinct NFC and NFD
versions of the same filename and on the backend supporting in-place
modtime updates. Dropbox normalizes unicode server-side (NFD -> NFC)
and can't set modtime in place, so the test inevitably takes a
different code path on Dropbox and the log diverges from the golden
output without any functional difference.
2026-05-07 18:08:37 +01:00
Nick Craig-Wood 895e56e401 test_all: give Cloudinary more list retries to fix flaky tests 2026-05-06 17:47:53 +01:00
Nick Craig-Wood 384e905373 fstest: make Retry helper public
Add a public fstest.Retry helper that retries any function with
exponential backoff up to *ListRetries attempts.
2026-05-06 17:47:53 +01:00
Nick Craig-Wood 38926f43be test_all: give Drime more list retries to fix flaky tests 2026-05-06 11:40:07 +01:00
Nick Craig-Wood 3e78426fc9 test_all: remove Webdav Infinite Scale integration tests
These are broken and the submitter has not shown any interest in
fixing them.
2026-05-06 11:40:07 +01:00
Nick Craig-Wood dac3fa851e test_all: remove Seafile V6 tests as they are broken and V6 is 10 years old 2026-05-06 11:40:07 +01:00
18899a58f3 Add Huawei Drive support
Add Huawei Drive backend implementation and tests

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Nick Craig-Wood <nick@craig-wood.com>
2026-05-01 13:41:07 +01:00
José ZúnigaandGitHub c385d8586a internxt: implement multi-part uploads
Implement multipart upload support with configurable chunk size and concurrency options

Enable OpenChunkWriter with per-chunk encryption

Enhance multipart upload handling with new upload cutoff and error management for small files
2026-04-24 17:20:18 +01:00
Nick Craig-Wood 9b889684b0 fstest/test_all: stop test servers on signal, panic, or exit
Until now test_all relied entirely on per-goroutine defer finish()
calls in fstest/runs to stop test servers. A Ctrl-C, kill, or panic
aborted those defers and left docker containers running, breaking the
next run.

Register testserver.CleanupAll with lib/atexit so SIGINT/SIGTERM
delivery runs the sweep automatically. Also defer atexit.Run for the
normal exit and unrecovered-panic paths, and call it explicitly
before os.Exit(1) since os.Exit does not fire defers. The fs.Fatalf
call sites above only fire before any server starts so they need no
explicit sweep.
2026-04-16 17:37:16 +01:00
Nick Craig-Wood 48a6584baf fstest/testserver: add CleanupAll for end-of-run server sweep
Cleanup today is entirely per-goroutine via the stop closure that Start
returns. If the driver process is killed or panics, those deferred
stops never run and the underlying container keeps running.

Track every remote Start has brought up in a process-local map, and
expose CleanupAll which force-stops each tracked remote via the new
run.bash "force-stop" verb. The returned stop closure is now
sync.Once-wrapped so it and CleanupAll can both fire harmlessly. No
callers yet; wired up in fstest/test_all in a follow-up commit.
2026-04-16 17:30:10 +01:00
Nick Craig-Wood 58a51c2ce9 fstest/testserver: add force-stop and reconcile stale refcounts
run.bash holds a persistent refcount file in the shared state directory
so multiple concurrent tests can share a single container. If a prior
test_all run is killed (e.g. Ctrl-C), the count never reaches zero on
the next run and the container is never stopped - forcing manual
cleanup.

Three fixes, all in fstest/testserver/init.d/run.bash:

- On start, if the refcount is non-zero but no container is running,
  treat it as zero. Stops leaking through future runs.
- reset now rm -rfs RUN_ROOT (the per-server state) instead of
  RUN_BASE (the shared parent) which was clobbering sibling services.
- New force-stop verb unconditionally stops the container and zeroes
  the refcount. This is the primitive that the Go-side cleanup sweep
  will call at end-of-run.
2026-04-16 17:29:06 +01:00
Nick Craig-Wood 26fb659fe4 test_all: increase retries for Internxt eventual consistency 2026-02-17 12:27:17 +00:00
Nick Craig-Wood 116d0f3708 test: allow backends to return fs.ErrorCantListRoot to skip Root tests 2026-01-30 17:50:18 +00:00
85d13c4e34 internxt: add Internxt backend - fixes #7610
Co-Authored-By: lullius <lullius@users.noreply.github.com>
Co-Authored-By: StarHack <StarHack@users.noreply.github.com>
2026-01-30 16:02:50 +00:00
Nick Craig-Wood 315a148820 test_all: allow drime more time to complete 2026-01-30 11:51:56 +00:00
Nick Craig-Wood 3a9c7ceeb1 uptobox: remove backend as service is no longer available
Uptobox was shutdown in September 2023 and does not appear to be
returning.
2026-01-14 15:31:46 +00:00
EndurielandNick Craig-Wood 9bef7f0dbf filen: add Filen backend - Fixes #6728 2026-01-13 12:50:27 +00:00
Nick Craig-Wood ecc5972d6f fstest: skip Copy mutation test with --sftp-copy-is-hardlink 2026-01-13 12:40:17 +00:00
Nick Craig-Wood 07805796ab fstest: Make Copy mutation test work properly
Before this change it could miss a mutation if the Modtime was cached
2026-01-13 12:40:17 +00:00
dougalandNick Craig-Wood 6529d2cd8f Add Drime backend
Co-Authored-By: Nick Craig-Wood <nick@craig-wood.com>
2026-01-08 12:05:37 +00:00
jhasse-shadeandGitHub 175d4bc553 Add Shade backend 2025-12-09 17:08:57 +00:00
Cliff FreyandGitHub f72b32b470 azureblob: add metadata and tags support across upload and copy paths
This change adds first-class metadata support to the Azure Blob backend,
including headers, user metadata, tags, and modtime overrides, and wires
it through uploads and server-side copies.

There is a behavior change in that rclone will now set the "mtime"
custom metadata when doing server side copies to azure and the
`--metadata` argument is given.

- Map standard headers: cache-control, content-disposition, content-encoding,
  content-language, content-type to corresponding x-ms-blob-* HTTP headers.
- Map user metadata: any non-reserved keys (excluding x-ms-*) are sent as
  blob user metadata. Keys are normalized to lowercase for consistency.
- Support tags: parse `x-ms-tags` as a comma-separated list of key=value
  pairs and apply them on uploads and copies.
- Support mtime override: accept `mtime` in metadata (RFC3339/RFC3339Nano)
  to override the stored modtime persisted in user metadata.
2025-11-27 16:58:07 +00:00
n4n5andGitHub 71138082ea fix: comment typos 2025-11-13 13:47:40 +00:00
Nick Craig-Wood fada870ff0 testserver: fix owncloud test server startup 2025-11-10 16:57:18 +00:00
Nick Craig-Wood fb895f69a1 testserver: fix HDFS server after run.bash adjustments 2025-11-05 17:56:28 +00:00
Nick Craig-Wood b204090325 testserver: remind developers about allocating a port 2025-11-05 17:56:28 +00:00
Nick Craig-Wood 1821d86911 testserver: make run.bash variables less likely to collide with scripts 2025-11-05 17:56:28 +00:00
Nick Craig-Wood 7ce67347fb testserver: fix seafile servers messing up _connect string 2025-11-05 17:56:28 +00:00
Nick Craig-Wood 0228bbff39 testserver: make sure TestWebdavInfiniteScale uses an assigned port 2025-11-05 17:56:28 +00:00
Nick Craig-Wood 6890bd7738 testserver: make sure we don't overwrite the NAME variable set
This fixes some oddities stopping and starting servers
2025-11-05 17:56:28 +00:00
AlexandGitHub 8f74e7d331 backend/compress: add zstd compression
Added support for reading and writing zstd-compressed archives in seekable format
using "github.com/klauspost/compress/zstd" and
"github.com/SaveTheRbtz/zstd-seekable-format-go/pkg".

Bumped Go version from 1.24.0 to 1.24.4 due to requirements of
"github.com/SaveTheRbtz/zstd-seekable-format-go/pkg".
2025-11-04 14:50:56 +00:00
Nick Craig-Wood 55655efabf testserver: fix tests failing due to stopped servers
Before this fix there were various issues with the test server
framework, most noticeably servers stopping when they shouldn't
causing timeouts. This was caused by the reference counting in the Go
code not being engineered to work in multiple processes so it was not
working at all properly.

This fix moves the reference counting logic to the start scripts and
in turn removes that logic from the Go code. This means that the
reference counting is now global and works correctly over multiple
processes.
2025-11-04 11:45:15 +00:00
Nick Craig-Wood d34ba258b0 test_all: fix detection of running servers
Before this change stopping servers was unreliable, expecially the non
docker based ones. This caused timeouts and connection errors in the
tests.
2025-11-03 14:44:39 +00:00
Nick Craig-Wood 203df6cc58 fstest: add ResetRun to allow the remote to be reset in tests 2025-10-30 16:20:48 +00:00
Nick Craig-Wood a0bcdc2638 Archive backend to read archives on cloud storage.
Initial support with Zip and Squashfs archives.

Fixes #8633
See #2815
2025-10-28 11:05:41 +00:00