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
179 lines
7.1 KiB
Go
179 lines
7.1 KiB
Go
package weed_server
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/credentials/insecure"
|
|
|
|
"github.com/seaweedfs/seaweedfs/weed/pb/volume_server_pb"
|
|
"github.com/seaweedfs/seaweedfs/weed/stats"
|
|
"github.com/seaweedfs/seaweedfs/weed/storage"
|
|
"github.com/seaweedfs/seaweedfs/weed/storage/erasure_coding"
|
|
"github.com/seaweedfs/seaweedfs/weed/storage/needle"
|
|
"github.com/seaweedfs/seaweedfs/weed/storage/types"
|
|
"github.com/seaweedfs/seaweedfs/weed/storage/volume_info"
|
|
"github.com/seaweedfs/seaweedfs/weed/util"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// newMultiDiskEcScrubStore builds a store with one DiskLocation per dir, so a
|
|
// volume whose shards are split across dirs mounts as one EcVolume per disk.
|
|
func newMultiDiskEcScrubStore(t *testing.T, dirs ...string) *storage.Store {
|
|
t.Helper()
|
|
max := make([]int32, len(dirs))
|
|
minFree := make([]util.MinFreeSpace, len(dirs))
|
|
diskTypes := make([]types.DiskType, len(dirs))
|
|
tags := make([][]string, len(dirs))
|
|
for i := range dirs {
|
|
max[i] = 10
|
|
diskTypes[i] = types.HardDriveType
|
|
}
|
|
// idxFolder shared so .ecx/.ecj resolve from any disk's index dir.
|
|
s := storage.NewStore(
|
|
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
|
"127.0.0.1", 0, 0, "", "test-store",
|
|
dirs, max, minFree,
|
|
dirs[0], storage.NeedleMapInMemory,
|
|
diskTypes, tags,
|
|
0, stats.DiskIOProbeConfig{},
|
|
)
|
|
t.Cleanup(s.Close)
|
|
return s
|
|
}
|
|
|
|
// seedEcShardOnDisk writes the minimal files for one shard id on one disk and
|
|
// mounts it. The .ecx is shared (one entry) so ScrubIndex/ScrubLocal can run.
|
|
func seedEcShardOnDisk(t *testing.T, store *storage.Store, vid needle.VolumeId, collection, dir string, shardId int, encodeTs int64, dataShards, parityShards int, blockSize int64) {
|
|
t.Helper()
|
|
base := erasure_coding.EcShardFileName(collection, dir, int(vid))
|
|
require.NoError(t, os.WriteFile(base+".ecx", make([]byte, types.NeedleMapEntrySize), 0o644))
|
|
require.NoError(t, os.WriteFile(base+".ecj", nil, 0o644))
|
|
require.NoError(t, os.WriteFile(base+erasure_coding.ToExt(shardId), []byte("s"), 0o644))
|
|
vif := &volume_server_pb.VolumeInfo{
|
|
Version: uint32(needle.Version3),
|
|
EcShardConfig: &volume_server_pb.EcShardConfig{
|
|
DataShards: uint32(dataShards),
|
|
ParityShards: uint32(parityShards),
|
|
BlockSize: blockSize,
|
|
EncodeTsNs: encodeTs,
|
|
},
|
|
}
|
|
require.NoError(t, volume_info.SaveVolumeInfo(base+".vif", vif))
|
|
require.NoError(t, store.MountEcShards(collection, vid, erasure_coding.ShardId(shardId), types.HardDriveType.String()))
|
|
}
|
|
|
|
// TestScrubEcVolume_DedupesSplitDiskVolume: a volume mounted on two disks must
|
|
// be scrubbed once (TotalVolumes == 1), not once per location.
|
|
func TestScrubEcVolume_DedupesSplitDiskVolume(t *testing.T) {
|
|
diskA, diskB := t.TempDir(), t.TempDir()
|
|
store := newMultiDiskEcScrubStore(t, diskA, diskB)
|
|
const vid = needle.VolumeId(900)
|
|
seedEcShardOnDisk(t, store, vid, "split", diskA, 0, 0, 10, 4, 0)
|
|
seedEcShardOnDisk(t, store, vid, "split", diskB, 1, 0, 10, 4, 0)
|
|
|
|
vs := &VolumeServer{store: store}
|
|
res, err := vs.scrubEcVolumes(
|
|
&volume_server_pb.ScrubEcVolumeRequest{Mode: volume_server_pb.VolumeScrubMode_INDEX},
|
|
[]needle.VolumeId{vid}, true)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, uint64(1), res.GetTotalVolumes(), "a split-disk volume must be scrubbed once, not once per disk")
|
|
}
|
|
|
|
// TestScrubEcVolume_FencesOnEncodeGeneration: a runtime from an older encode
|
|
// run must be excluded and reported, not merged into the scrub.
|
|
func TestScrubEcVolume_FencesOnEncodeGeneration(t *testing.T) {
|
|
diskA, diskB := t.TempDir(), t.TempDir()
|
|
store := newMultiDiskEcScrubStore(t, diskA, diskB)
|
|
const vid = needle.VolumeId(901)
|
|
seedEcShardOnDisk(t, store, vid, "gen", diskA, 0, 1000, 10, 4, 0)
|
|
seedEcShardOnDisk(t, store, vid, "gen", diskB, 1, 500, 10, 4, 0)
|
|
|
|
vs := &VolumeServer{store: store}
|
|
res, err := vs.scrubEcVolumes(
|
|
&volume_server_pb.ScrubEcVolumeRequest{Mode: volume_server_pb.VolumeScrubMode_INDEX},
|
|
[]needle.VolumeId{vid}, true)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, uint64(1), res.GetTotalVolumes())
|
|
var foundSkip bool
|
|
for _, d := range res.GetDetails() {
|
|
if strings.Contains(d, "belong to encode run 500") {
|
|
foundSkip = true
|
|
}
|
|
}
|
|
assert.True(t, foundSkip, "older encode-generation runtime must be reported as skipped, got details: %v", res.GetDetails())
|
|
}
|
|
|
|
// TestScrubEcVolume_FencesOnGeometry: same encode timestamp but disagreeing
|
|
// geometry must exclude and report the incompatible runtime.
|
|
func TestScrubEcVolume_FencesOnGeometry(t *testing.T) {
|
|
diskA, diskB := t.TempDir(), t.TempDir()
|
|
store := newMultiDiskEcScrubStore(t, diskA, diskB)
|
|
const vid = needle.VolumeId(902)
|
|
seedEcShardOnDisk(t, store, vid, "geo", diskA, 0, 1000, 10, 4, 3*1024*1024)
|
|
seedEcShardOnDisk(t, store, vid, "geo", diskB, 1, 1000, 12, 4, 3*1024*1024)
|
|
|
|
vs := &VolumeServer{store: store}
|
|
res, err := vs.scrubEcVolumes(
|
|
&volume_server_pb.ScrubEcVolumeRequest{Mode: volume_server_pb.VolumeScrubMode_INDEX},
|
|
[]needle.VolumeId{vid}, true)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, uint64(1), res.GetTotalVolumes())
|
|
var foundGeoSkip bool
|
|
for _, d := range res.GetDetails() {
|
|
if strings.Contains(d, "disagree on geometry") {
|
|
foundGeoSkip = true
|
|
}
|
|
}
|
|
assert.True(t, foundGeoSkip, "geometry-mismatched runtime must be reported as skipped, got details: %v", res.GetDetails())
|
|
}
|
|
|
|
// TestScrubEcVolume_LocalReachesSiblingDisk: LOCAL mode over a split-disk
|
|
// volume must see shards from both disks (the merged view), not just the
|
|
// first. With both shards local, the index walk has no missing-shard error.
|
|
func TestScrubEcVolume_LocalReachesSiblingDisk(t *testing.T) {
|
|
diskA, diskB := t.TempDir(), t.TempDir()
|
|
store := newMultiDiskEcScrubStore(t, diskA, diskB)
|
|
const vid = needle.VolumeId(903)
|
|
seedEcShardOnDisk(t, store, vid, "sib", diskA, 0, 0, 10, 4, 0)
|
|
seedEcShardOnDisk(t, store, vid, "sib", diskB, 1, 0, 10, 4, 0)
|
|
|
|
vs := &VolumeServer{store: store}
|
|
res, err := vs.scrubEcVolumes(
|
|
&volume_server_pb.ScrubEcVolumeRequest{Mode: volume_server_pb.VolumeScrubMode_LOCAL},
|
|
[]needle.VolumeId{vid}, true)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, uint64(1), res.GetTotalVolumes())
|
|
}
|
|
|
|
// TestMergeEcRuntimes_ReportsAnchorGeneration: the anchor is the maximum
|
|
// encode generation, and a single-runtime volume anchors on itself.
|
|
func TestMergeEcRuntimes_ReportsAnchorGeneration(t *testing.T) {
|
|
dir := t.TempDir()
|
|
store := newMultiDiskEcScrubStore(t, dir)
|
|
const vid = needle.VolumeId(904)
|
|
seedEcShardOnDisk(t, store, vid, "anchor", dir, 0, 7777, 10, 4, 0)
|
|
|
|
runtimes := store.FindAllEcVolumes(vid)
|
|
require.Len(t, runtimes, 1)
|
|
merged := erasure_coding.MergeEcRuntimes(runtimes)
|
|
require.NotNil(t, merged)
|
|
assert.Equal(t, int64(7777), merged.Anchor.EncodeTsNs)
|
|
assert.Empty(t, merged.Skipped)
|
|
assert.Len(t, merged.Merged, 1)
|
|
}
|
|
|
|
// TestMergeEcRuntimes_NilForEmptyInput: an empty runtime slice (vanished
|
|
// volume) yields a nil merged view.
|
|
func TestMergeEcRuntimes_NilForEmptyInput(t *testing.T) {
|
|
assert.Nil(t, erasure_coding.MergeEcRuntimes(nil))
|
|
assert.Nil(t, erasure_coding.MergeEcRuntimes([]*erasure_coding.EcVolume{}))
|
|
}
|
|
|
|
// Ensure filepath import is used (helper for future multi-disk tests).
|
|
var _ = filepath.Join
|