mirror of
https://github.com/hanzoai/s3.git
synced 2026-11-03 03:07:41 +00:00
hanzoai/s3 was an AGPL-3.0 MinIO fork whose network-copyleft blocks embedding
and reselling as a managed service. Replace it wholesale with a fork of
SeaweedFS (github.com/seaweedfs/seaweedfs, Apache-2.0, Go) which ships a
built-in S3 gateway + Filer.
- License: AGPL-3.0 -> Apache-2.0 (upstream LICENSE kept verbatim, incl.
"Copyright 2025 Chris Lu"); NOTICE added crediting SeaweedFS. No AGPL/BUSL/
SSPL/GPL or enterprise ("ee") files remain.
- Module: go.mod path set to github.com/hanzoai/s3 with a self-replace
(replace github.com/seaweedfs/seaweedfs => ./) so the ~1800 internal Go files
keep their upstream import paths with zero churn. Internal identifiers and
import paths are intentionally NOT renamed.
- CLI rebrand: the binary is built as `s3` (was `weed`); root usage, per-command
help/usage/flag strings, shell autocomplete program name, and the product name
in CLI output now read "Hanzo S3" / `s3`. Users never see `weed`.
(e.g. `s3 server`, `s3 filer`, `s3 master`, `s3 volume`, `s3 s3`, `s3 mount`.)
- Build: `make` (or `go build -o s3 ./weed`) builds the `s3` binary green;
`cmd/weed-db` and `cmd/weed-sql` also build; `go vet ./weed/command/` clean.
- README/LLM.md rewritten for Hanzo S3; AGENTS.md/CLAUDE.md symlinks preserved.
- Dropped a 33MB prebuilt Mach-O `stress` binary upstream had committed; `.gitignore`
updated to ignore the `s3` build output.
88 lines
2.1 KiB
Go
88 lines
2.1 KiB
Go
package weed_server
|
|
|
|
import (
|
|
"sort"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/raft"
|
|
"github.com/seaweedfs/seaweedfs/weed/pb"
|
|
)
|
|
|
|
func TestRaftServerID(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
addr pb.ServerAddress
|
|
want string
|
|
}{
|
|
{
|
|
name: "without grpc suffix",
|
|
addr: pb.ServerAddress("master-0:9333"),
|
|
want: "master-0:9333",
|
|
},
|
|
{
|
|
name: "with grpc suffix",
|
|
addr: pb.NewServerAddress("master-0", 9333, 19333),
|
|
want: "master-0:9333",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := raftServerID(tt.addr); got != tt.want {
|
|
t.Fatalf("raftServerID(%q) = %q, want %q", tt.addr, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetPeerIdxUsesCanonicalID(t *testing.T) {
|
|
peers := map[string]pb.ServerAddress{
|
|
"master-0:9333": pb.ServerAddress("master-0:9333"),
|
|
"master-1:9333": pb.ServerAddress("master-1:9333"),
|
|
"master-2:9333": pb.ServerAddress("master-2:9333"),
|
|
}
|
|
self := pb.NewServerAddress("master-2", 9333, 19333)
|
|
|
|
if got := getPeerIdx(self, peers); got != 2 {
|
|
t.Fatalf("getPeerIdx(%q) = %d, want 2", self, got)
|
|
}
|
|
}
|
|
|
|
func TestAddPeersConfigurationUsesCanonicalIDs(t *testing.T) {
|
|
rs := &RaftServer{
|
|
peers: map[string]pb.ServerAddress{
|
|
"master-0:9333": pb.ServerAddress("master-0:9333"),
|
|
"master-1:9333": pb.ServerAddress("master-1:9333"),
|
|
"master-2:9333": pb.ServerAddress("master-2:9333"),
|
|
},
|
|
}
|
|
|
|
cfg := rs.AddPeersConfiguration()
|
|
if len(cfg.Servers) != 3 {
|
|
t.Fatalf("len(cfg.Servers) = %d, want 3", len(cfg.Servers))
|
|
}
|
|
|
|
var ids []string
|
|
var addrs []string
|
|
for _, s := range cfg.Servers {
|
|
if s.Suffrage != raft.Voter {
|
|
t.Fatalf("server %q has suffrage %q, want %q", s.ID, s.Suffrage, raft.Voter)
|
|
}
|
|
ids = append(ids, string(s.ID))
|
|
addrs = append(addrs, string(s.Address))
|
|
}
|
|
sort.Strings(ids)
|
|
sort.Strings(addrs)
|
|
|
|
wantIDs := []string{"master-0:9333", "master-1:9333", "master-2:9333"}
|
|
wantAddrs := []string{"master-0:19333", "master-1:19333", "master-2:19333"}
|
|
for i := range wantIDs {
|
|
if ids[i] != wantIDs[i] {
|
|
t.Fatalf("ids[%d] = %q, want %q", i, ids[i], wantIDs[i])
|
|
}
|
|
if addrs[i] != wantAddrs[i] {
|
|
t.Fatalf("addrs[%d] = %q, want %q", i, addrs[i], wantAddrs[i])
|
|
}
|
|
}
|
|
}
|