Files
seaweedfs/weed/pb/filer_pb/filer_pb_helper_test.go
T
Chris Lu 63f2f0bef5 s3: keep a file promoted to a directory retrievable as an object (#10070)
* filer: treat a directory carrying object data as an S3 key object

A file promoted to a directory by a child write keeps its chunks, inline
content, or remote-tiered entry. Recognize that as a directory key object,
not only when a Mime is set, so the object still lists, demotes on delete,
and is not reclaimed by cleanup like the object it still is.

* filer: keep the empty-folder cleaner from reclaiming a promoted object

The cleaner skips directory key objects, but its check only looked at the
Mime. Mirror the chunks/content/remote check so a file promoted to a
directory is not deleted once its children are gone.

* s3: serve ranged GET for a directory that carries object data

Reject only zero-size directories so a file promoted to a directory streams
range requests instead of returning 404, while empty directories still 404.

* s3: return HEAD metadata for a directory that carries object data

HEAD now 404s a directory only when it has no data, so a promoted object is
retrievable while empty/implicit directories still fall back to LIST.
2026-06-23 14:06:00 -07:00

33 lines
1.4 KiB
Go

package filer_pb
import (
"testing"
)
func TestIsDirectoryKeyObject(t *testing.T) {
chunk := []*FileChunk{{FileId: "1,01", Size: 75}}
cases := []struct {
name string
e *Entry
want bool
}{
{"plain directory", &Entry{IsDirectory: true, Attributes: &FuseAttributes{}}, false},
{"directory marker with mime", &Entry{IsDirectory: true, Attributes: &FuseAttributes{Mime: "application/octet-stream"}}, true},
{"directory promoted from file keeps chunks", &Entry{IsDirectory: true, Attributes: &FuseAttributes{}, Chunks: chunk}, true},
{"directory promoted from small file keeps content", &Entry{IsDirectory: true, Attributes: &FuseAttributes{}, Content: []byte("abc")}, true},
{"directory promoted from remote-tiered file", &Entry{IsDirectory: true, Attributes: &FuseAttributes{}, RemoteEntry: &RemoteEntry{RemoteSize: 100}}, true},
{"directory with chunks and nil attributes", &Entry{IsDirectory: true, Chunks: chunk}, true},
{"regular file with chunks", &Entry{IsDirectory: false, Attributes: &FuseAttributes{}, Chunks: chunk}, false},
{"remote mount directory has no remote size", &Entry{IsDirectory: true, Attributes: &FuseAttributes{}, RemoteEntry: &RemoteEntry{StorageName: "s3"}}, false},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
if got := c.e.IsDirectoryKeyObject(); got != c.want {
t.Errorf("IsDirectoryKeyObject() = %v, want %v", got, c.want)
}
})
}
}