mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-11-06 03:57:48 +01:00
* 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.
33 lines
1.4 KiB
Go
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)
|
|
}
|
|
})
|
|
}
|
|
}
|