snapshot of https://github.com/seaweedfs/seaweedfs.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
go: build dev binaries / cleanup (push) Successful in 4s
Codespell / Check for spelling errors (push) Failing after 3s
docker: build dev containers / build-rust-binaries (amd64, x86_64-unknown-linux-musl) (push) Failing after 3s
docker: build dev containers / build-dev-containers (push) Has been skipped
docker: build dev containers / build-rust-binaries (arm64, true, aarch64-unknown-linux-musl) (push) Failing after 3s
End to End / FUSE Mount (push) Failing after 2s
EC Integration Tests / EC Integration Tests (push) Failing after 30s
FUSE DLM Integration Tests / FUSE DLM Integration Tests (push) Failing after 3s
FUSE Volume Server Failover Tests / FUSE Volume Server Failover (push) Failing after 3s
FUSE Integration Tests / FUSE Integration Testing (push) Failing after 2s
FUSE P2P Peer Chunk Sharing Integration Tests / FUSE P2P Peer Chunk Sharing (push) Failing after 3s
go: build binary / Go Vet (push) Failing after 2s
go: build binary / Go Vet 32-bit (push) Failing after 3s
go: build binary / Build (push) Failing after 4s
go: build binary / Build cross-platform (freebsd/amd64) (push) Failing after 3s
go: build binary / Build cross-platform (windows/amd64) (push) Failing after 3s
go: build binary / Build cross-platform (darwin/arm64) (push) Failing after 3s
go: build binary / Build cross-platform (windows/arm64) (push) Failing after 3s
go: build binary / Test (push) Failing after 2s
go: build binary / Test 32-bit (push) Failing after 3s
helm: lint and test charts / lint-test (push) Failing after 3s
Java Client Integration Tests / Java Integration Tests (11) (push) Failing after 3s
Java Client Integration Tests / Java Integration Tests (17) (push) Failing after 3s
go: build dev binaries / build_dev_linux_windows (amd64, linux) (push) Failing after 2s
go: build dev binaries / build_dev_linux_windows (amd64, windows) (push) Failing after 3s
go: build dev binaries / build_dev_darwin (amd64, darwin) (push) Has been skipped
go: build dev binaries / build_dev_darwin (arm64, darwin) (push) Has been skipped
Java Client Unit Tests / Java Unit Tests (11) (push) Failing after 3s
Java Client Unit Tests / Java Unit Tests (17) (push) Failing after 2s
Java Client Unit Tests / Java Unit Tests (21) (push) Failing after 3s
Java Client Unit Tests / Java Unit Tests (8) (push) Failing after 3s
Kafka Quick Test (Load Test with Schema Registry) / Kafka Client Load Test (Quick) (push) Failing after 3s
Kafka Gateway Tests / Kafka Unit Tests (unit-tests-1) (push) Failing after 11s
Kafka Gateway Tests / Kafka Integration Tests (Critical) (integration-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka End-to-End Tests (with SMQ) (e2e-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka Consumer Group Tests (Highly Isolated) (consumer-group-1) (push) Failing after 2s
Kafka Gateway Tests / Kafka Client Compatibility (with SMQ) (client-compat-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka SMQ Integration Tests (Full Stack) (smq-integration-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka Protocol Tests (Isolated) (protocol-1) (push) Failing after 3s
KMS Tests / KMS Provider Integration Tests (push) Failing after 2s
KMS Tests / S3 KMS End-to-End Tests (push) Failing after 3s
Master Cold Start Tests / Master Cold Start Tests (push) Failing after 4s
Metadata Subscribe Integration Tests / Metadata Subscribe Integration Tests (push) Failing after 3s
Multi-Master Tests / Multi-Master Failover Tests (push) Failing after 3s
Performance / CPU and Heap Profile (push) Failing after 2s
Performance / S3 Read/Write Benchmark (rust volume) (push) Failing after 3s
pjdfstest POSIX Compliance / pjdfstest (push) Failing after 2s
Plugin Worker Integration Tests / Plugin Worker: erasure_coding (push) Failing after 3s
Plugin Worker Integration Tests / Plugin Worker: vacuum (push) Failing after 3s
Rust Volume Server Tests / Rust Integration Tests (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (grpc - Shard 1) (push) Failing after 2s
Rust Volume Server Tests / Go Tests with Rust Volume (http - Shard 1) (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (grpc - Shard 2) (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (http - Shard 2) (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (grpc - Shard 3) (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Distributed Tests (push) Failing after 2s
S3 IAM Integration Tests / S3 IAM Performance Tests (push) Failing after 3s
Performance / Throughput Benchmark (go volume) (push) Failing after 3s
Performance / Throughput Benchmark (rust volume) (push) Failing after 2s
Performance / S3 Read/Write Benchmark (go volume) (push) Failing after 3s
Plugin Worker Integration Tests / Plugin Worker: volume_balance (push) Failing after 3s
PostgreSQL Gateway Tests / PostgreSQL Basic Tests (push) Failing after 3s
Rust Volume Server Tests / Rust Unit Tests (push) Failing after 2s
Rust Volume Server Tests / Go Tests with Rust Volume (http - Shard 3) (push) Failing after 3s
Rust Plugin Worker Tests / Rust Plugin Worker Build and Unit Tests (push) Failing after 3s
rust: build dev volume server binaries / cleanup (push) Successful in 3s
S3 ETag and ACL Tests / S3 ETag + ACL Integration Tests (push) Failing after 3s
S3 IAM Integration Tests / IAM Unit Tests (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Integration Tests (advanced) (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Integration Tests (basic) (push) Failing after 2s
S3 IAM Integration Tests / S3 IAM Integration Tests (group) (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Integration Tests (policy-enforcement) (push) Failing after 2s
S3 IAM Integration Tests / S3 IAM Integration Tests (sts) (push) Failing after 4s
S3 Keycloak Integration Tests / S3 Keycloak Integration Tests (push) Failing after 3s
S3 PyArrow Parquet Tests / PyArrow Parquet Tests (Python 3.11) (push) Failing after 3s
S3 PyArrow Parquet Tests / Go Unit Tests (Implicit Directory) (push) Has been cancelled
S3 PyArrow Parquet Tests / PyArrow Parquet Tests (Python 3.12) (push) Has been cancelled
rust: build dev volume server binaries / build-rust-volume-dev-darwin (darwin-amd64, x86_64-apple-darwin) (push) Has been cancelled
rust: build dev volume server binaries / build-rust-volume-dev-darwin (darwin-arm64, aarch64-apple-darwin) (push) Has been cancelled
rust: build dev volume server binaries / build-rust-volume-dev-linux (linux-amd64, x86_64-unknown-linux-gnu) (push) Has been cancelled
S3 PyArrow Parquet Tests / PyArrow Parquet Tests (Python 3.9) (push) Has been cancelled
S3 Proxy Signature Tests / S3 Proxy Signature Verification Tests (push) Has been cancelled
S3 SDK V2 Route Disambiguation Tests / S3 SDK V2 Routing Tests (push) Has been cancelled
S3 SSE Tests / S3 SSE Integration Tests (quick) (push) Has been cancelled
S3 SSE Tests / S3 SSE Compatibility Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Metadata Persistence Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Copy Operations Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Multipart Upload Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Performance Test (push) Has been cancelled
S3 SSE Tests / S3 Volume Encryption Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Integration Tests (comprehensive) (push) Has been cancelled
Spark Integration Tests / Spark Integration Tests (push) Failing after 2s
Telemetry Integration Tests / telemetry-integration-test (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (grpc - Shard 1) (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (http - Shard 1) (push) Failing after 3s
Ceph S3 tests / Basic S3 tests (KV store) (push) Has been cancelled
Ceph S3 tests / S3 Versioning & Object Lock tests (push) Has been cancelled
S3 Policy Integration Tests / S3 Policy Unit Tests (push) Failing after 3s
Ceph S3 tests / S3 CORS tests (push) Has been cancelled
Ceph S3 tests / SeaweedFS Custom S3 Copy tests (push) Has been cancelled
Ceph S3 tests / Basic S3 tests (SQL store) (push) Has been cancelled
test s3 over https using aws-cli / awscli-tests (push) Has been cancelled
TLS Rotation Integration Tests / TLS Rotation Integration Tests (push) Has been cancelled
Vacuum Integration Tests / Vacuum Integration Tests (push) Has been cancelled
S3 Policy Integration Tests / S3 Policy Variables Integration Tests (push) Failing after 3s
S3 Policy Integration Tests / S3 Policy Enforcement Integration Tests (advanced-policy) (push) Failing after 3s
S3 Policy Integration Tests / S3 Policy Enforcement Integration Tests (basic-policy) (push) Failing after 2s
S3 Policy Integration Tests / S3 Policy Enforcement Integration Tests (contextual-policy) (push) Failing after 4s
S3 Policy Integration Tests / Trusted Proxy Detection Tests (push) Failing after 2s
S3 Policy Integration Tests / S3 Policy Shell Integration Tests (push) Failing after 3s
Samba on FUSE Integration / samba-integration (push) Failing after 2s
SFTP Integration Tests / SFTP Integration Testing (push) Failing after 3s
terraform: validate and test modules / fmt, validate, plan-level tests (push) Failing after 3s
terraform: validate and test modules / local cluster smoke test (real weed) (push) Failing after 2s
Volume Server Integration Tests / Volume Server Integration Tests (grpc - Shard 3) (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (grpc - Shard 2) (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (http - Shard 2) (push) Failing after 2s
Volume Server Integration Tests / Volume Server Integration Tests (http - Shard 3) (push) Failing after 5s
mount: windows conformance / WinFsp conformance (push) Has been cancelled
mount: windows / Mount on Windows (push) Has been cancelled

This commit is contained in:
upstream-mirror
2026-09-16 03:23:42 +05:00
commit 89f5be005d
3997 changed files with 961970 additions and 0 deletions

View File

@@ -0,0 +1,269 @@
package winfsp
import (
"fmt"
"sync"
"testing"
"time"
"github.com/seaweedfs/go-fuse/v2/fuse"
)
type forgetRecorder struct {
mu sync.Mutex
inodes []uint64
}
func (r *forgetRecorder) forget(inode uint64) {
r.mu.Lock()
defer r.mu.Unlock()
r.inodes = append(r.inodes, inode)
}
func (r *forgetRecorder) forgotten() []uint64 {
r.mu.Lock()
defer r.mu.Unlock()
return append([]uint64(nil), r.inodes...)
}
func TestPathCacheLookupAndExpiry(t *testing.T) {
rec := &forgetRecorder{}
c := newPathCache(20*time.Millisecond, rec.forget)
c.insert("a/b", 7, fuse.Attr{Ino: 7, Size: 42}, c.snapshot())
inode, attr, ok := c.lookup("a/b")
if !ok || inode != 7 || attr.Size != 42 {
t.Fatalf("lookup = %d %v %v, want 7 size 42 true", inode, attr.Size, ok)
}
time.Sleep(30 * time.Millisecond)
if _, _, ok := c.lookup("a/b"); ok {
t.Fatal("expired entry still served")
}
// The reference survives at least one sweep past expiry before it is
// forgotten: one insert moves it to the graveyard, the next returns it.
c.insert("x", 8, fuse.Attr{}, c.snapshot())
time.Sleep(30 * time.Millisecond)
c.insert("y", 9, fuse.Attr{}, c.snapshot())
found := false
for _, inode := range rec.forgotten() {
if inode == 7 {
found = true
}
}
if !found {
t.Fatalf("expired reference never forgotten; forgot %v", rec.forgotten())
}
}
func TestPathCacheStealTransfersOwnership(t *testing.T) {
rec := &forgetRecorder{}
c := newPathCache(20*time.Millisecond, rec.forget)
c.insert("a", 5, fuse.Attr{}, c.snapshot())
inode, ok := c.steal("a")
if !ok || inode != 5 {
t.Fatalf("steal = %d %v, want 5 true", inode, ok)
}
if _, ok := c.steal("a"); ok {
t.Fatal("second steal succeeded")
}
// Drive several sweeps; the stolen reference must never be forgotten.
for i := 0; i < 4; i++ {
time.Sleep(25 * time.Millisecond)
c.insert("churn", uint64(100+i), fuse.Attr{}, c.snapshot())
}
for _, inode := range rec.forgotten() {
if inode == 5 {
t.Fatal("stolen reference was forgotten by the cache")
}
}
}
func TestPathCacheReplaceReturnsOldReference(t *testing.T) {
rec := &forgetRecorder{}
c := newPathCache(20*time.Millisecond, rec.forget)
c.insert("a", 5, fuse.Attr{}, c.snapshot())
c.insert("a", 6, fuse.Attr{}, c.snapshot())
if inode, _, ok := c.lookup("a"); !ok || inode != 6 {
t.Fatalf("lookup after replace = %d %v, want 6 true", inode, ok)
}
for i := 0; i < 3; i++ {
time.Sleep(25 * time.Millisecond)
c.insert("churn", uint64(100+i), fuse.Attr{}, c.snapshot())
}
found := false
for _, inode := range rec.forgotten() {
if inode == 5 {
found = true
}
if inode == 6 && !found {
t.Fatal("live reference forgotten before the replaced one")
}
}
if !found {
t.Fatalf("replaced reference never forgotten; forgot %v", rec.forgotten())
}
}
func TestPathCachePurgePrefix(t *testing.T) {
rec := &forgetRecorder{}
c := newPathCache(time.Minute, rec.forget)
c.insert("dir", 2, fuse.Attr{}, c.snapshot())
c.insert("dir/a", 3, fuse.Attr{}, c.snapshot())
c.insert("dir/a/b", 4, fuse.Attr{}, c.snapshot())
c.insert("dirt", 5, fuse.Attr{}, c.snapshot())
c.purge("dir", true)
if _, _, ok := c.lookup("dir"); ok {
t.Fatal("purged key still cached")
}
if _, _, ok := c.lookup("dir/a/b"); ok {
t.Fatal("purged subtree still cached")
}
// A sibling that only shares the name as a string prefix stays.
if _, _, ok := c.lookup("dirt"); !ok {
t.Fatal("sibling was purged with the subtree")
}
}
func TestPathCacheRootNeverCached(t *testing.T) {
rec := &forgetRecorder{}
c := newPathCache(time.Minute, rec.forget)
c.insert("", 9, fuse.Attr{}, c.snapshot())
if _, _, ok := c.lookup(""); ok {
t.Fatal("root was cached")
}
if got := rec.forgotten(); len(got) != 1 || got[0] != 9 {
t.Fatalf("root reference not returned immediately: %v", got)
}
}
func TestCacheKey(t *testing.T) {
for path, want := range map[string]string{
`/a/b`: "a/b",
`\a\b`: "a/b",
`a//b/`: "a/b",
`/`: "",
``: "",
`/a/./b`: "a/b",
} {
if got := cacheKey(path); got != want {
t.Errorf("cacheKey(%q) = %q, want %q", path, got, want)
}
}
}
// A resolve runs its Lookup outside the cache lock, so a purge can land
// between the RPC and the insert. An insert a purge covered must then be
// discarded: it carries exactly the name the purge removed, and caching it
// would serve a deleted entry for a full ttl. This is how a rename's source
// briefly came back from the dead on the Windows mount.
func TestPathCacheInsertAfterCoveringPurgeIsDiscarded(t *testing.T) {
c := newPathCache(time.Minute, func(uint64) {})
gen := c.snapshot()
c.purge("dir/src", false)
c.insert("dir/src", 42, fuse.Attr{}, gen)
if _, _, ok := c.lookup("dir/src"); ok {
t.Fatal("purged name served from an insert that started before the purge")
}
}
// A purge of a directory covers the resolves in flight under it.
func TestPathCacheInsertUnderPurgedPrefixIsDiscarded(t *testing.T) {
c := newPathCache(time.Minute, func(uint64) {})
gen := c.snapshot()
c.purge("dir", true)
c.insert("dir/child", 7, fuse.Attr{}, gen)
if _, _, ok := c.lookup("dir/child"); ok {
t.Fatal("purged prefix served a child from a stale insert")
}
}
// A purge of something else entirely must not discard the insert: an open
// retries resolve-then-steal only a few times before giving up with EIO, so
// unrelated churn starving every insert would fail opens of untouched paths.
func TestPathCacheUnrelatedPurgeDoesNotDiscard(t *testing.T) {
c := newPathCache(time.Minute, func(uint64) {})
gen := c.snapshot()
c.purge("elsewhere", true)
c.purge("dir/srcling", false)
c.insert("dir/src", 9, fuse.Attr{Size: 11}, gen)
inode, attr, ok := c.lookup("dir/src")
if !ok || inode != 9 || attr.Size != 11 {
t.Fatalf("lookup = %d,%d,%v, want the inserted entry", inode, attr.Size, ok)
}
}
// Purges beyond the remembered window cannot be checked by key, so the insert
// is discarded rather than trusted.
func TestPathCacheInsertOlderThanPurgeWindowIsDiscarded(t *testing.T) {
c := newPathCache(time.Minute, func(uint64) {})
gen := c.snapshot()
for i := 0; i <= maxRecentPurges; i++ {
c.purge(fmt.Sprintf("unrelated/%d", i), false)
}
c.insert("dir/src", 3, fuse.Attr{}, gen)
if _, _, ok := c.lookup("dir/src"); ok {
t.Fatal("insert older than the purge window was trusted")
}
}
// The discarded insert still owns a lookup reference, which has to come back
// through the graveyard rather than leak - and not in the same call: the
// walker is still using the inode.
func TestPathCacheDiscardedInsertRestsBeforeForget(t *testing.T) {
rec := &forgetRecorder{}
c := newPathCache(10*time.Millisecond, rec.forget)
gen := c.snapshot()
c.purge("dir/src", false)
// Make a sweep due, so the discarding insert itself sweeps: the reference
// it just parked must not come back out of that same call.
time.Sleep(15 * time.Millisecond)
c.insert("dir/src", 42, fuse.Attr{}, gen)
for _, inode := range rec.forgotten() {
if inode == 42 {
t.Fatal("discarded insert forgotten in the same call; the walker still holds it")
}
}
for i := 0; i < 3; i++ {
time.Sleep(15 * time.Millisecond)
c.purge("churn", false)
}
found := false
for _, inode := range rec.forgotten() {
if inode == 42 {
found = true
}
}
if !found {
t.Fatalf("discarded insert leaked its lookup reference; forgot %v", rec.forgotten())
}
}
// A purge of the whole cache - the root, prefix set - covers every in-flight
// insert, exactly as it removed every entry.
func TestPathCacheRootPurgeCoversEveryInsert(t *testing.T) {
c := newPathCache(time.Minute, func(uint64) {})
gen := c.snapshot()
c.purge("", true)
c.insert("dir/src", 42, fuse.Attr{}, gen)
if _, _, ok := c.lookup("dir/src"); ok {
t.Fatal("root purge did not cover an in-flight insert")
}
}