mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 02:42:27 +00:00
cmd/swarm/swarm-snapshot: add more comments and other minor adjustments
This commit is contained in:
parent
186dd02c3d
commit
b226052576
5 changed files with 52 additions and 29 deletions
|
|
@ -38,8 +38,9 @@ import (
|
||||||
cli "gopkg.in/urfave/cli.v1"
|
cli "gopkg.in/urfave/cli.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
const noConnectionTimeout = 2 * time.Second
|
const noConnectionTimeout = 1 * time.Second
|
||||||
|
|
||||||
|
// create is used as the entry function for "create" app command.
|
||||||
func create(ctx *cli.Context) error {
|
func create(ctx *cli.Context) error {
|
||||||
log.PrintOrigins(true)
|
log.PrintOrigins(true)
|
||||||
log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(ctx.Int("verbosity")), log.StreamHandler(os.Stdout, log.TerminalFormat(true))))
|
log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(ctx.Int("verbosity")), log.StreamHandler(os.Stdout, log.TerminalFormat(true))))
|
||||||
|
|
@ -51,14 +52,16 @@ func create(ctx *cli.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return createSnapshot(filename, ctx.Int("nodes"), ctx.String("services"))
|
return createSnapshot(filename, ctx.Int("nodes"), strings.Split(ctx.String("services"), ","))
|
||||||
}
|
}
|
||||||
|
|
||||||
func createSnapshot(filename string, nodes int, services string) (err error) {
|
// createSnapshot creates a new snapshot on filesystem with provided filename,
|
||||||
|
// number of nodes and service names.
|
||||||
|
func createSnapshot(filename string, nodes int, services []string) (err error) {
|
||||||
log.Debug("create snapshot", "filename", filename, "nodes", nodes, "services", services)
|
log.Debug("create snapshot", "filename", filename, "nodes", nodes, "services", services)
|
||||||
|
|
||||||
sim := simulation.New(map[string]simulation.ServiceFunc{
|
sim := simulation.New(map[string]simulation.ServiceFunc{
|
||||||
bzzServiceName: func(ctx *adapters.ServiceContext, b *sync.Map) (node.Service, func(), error) {
|
"bzz": func(ctx *adapters.ServiceContext, b *sync.Map) (node.Service, func(), error) {
|
||||||
addr := network.NewAddr(ctx.Config.Node())
|
addr := network.NewAddr(ctx.Config.Node())
|
||||||
kad := network.NewKademlia(addr.Over(), network.NewKadParams())
|
kad := network.NewKademlia(addr.Over(), network.NewKadParams())
|
||||||
hp := network.NewHiveParams()
|
hp := network.NewHiveParams()
|
||||||
|
|
@ -80,6 +83,8 @@ func createSnapshot(filename string, nodes int, services string) (err error) {
|
||||||
return fmt.Errorf("add nodes: %v", err)
|
return fmt.Errorf("add nodes: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// wait for two some time to ensure no connections
|
||||||
|
// are established
|
||||||
events := make(chan *simulations.Event)
|
events := make(chan *simulations.Event)
|
||||||
sub := sim.Net.Events().Subscribe(events)
|
sub := sim.Net.Events().Subscribe(events)
|
||||||
select {
|
select {
|
||||||
|
|
@ -109,19 +114,21 @@ func createSnapshot(filename string, nodes int, services string) (err error) {
|
||||||
|
|
||||||
var snap *simulations.Snapshot
|
var snap *simulations.Snapshot
|
||||||
if len(services) > 0 {
|
if len(services) > 0 {
|
||||||
addServices := strings.Split(services, ",")
|
// If service names are provided, include them in the snapshot.
|
||||||
|
// But, check if "bzz" service is not among them to remove it
|
||||||
|
// form the snapshot as it exists on snapshot creation.
|
||||||
var removeServices []string
|
var removeServices []string
|
||||||
var hasBzz bool
|
var wantBzz bool
|
||||||
for _, s := range addServices {
|
for _, s := range services {
|
||||||
if s == bzzServiceName {
|
if s == "bzz" {
|
||||||
hasBzz = true
|
wantBzz = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !hasBzz {
|
if !wantBzz {
|
||||||
removeServices = append(removeServices, bzzServiceName)
|
removeServices = []string{"bzz"}
|
||||||
}
|
}
|
||||||
snap, err = sim.Net.SnapshotWithServices(addServices, removeServices)
|
snap, err = sim.Net.SnapshotWithServices(services, removeServices)
|
||||||
} else {
|
} else {
|
||||||
snap, err = sim.Net.Snapshot()
|
snap, err = sim.Net.Snapshot()
|
||||||
}
|
}
|
||||||
|
|
@ -135,6 +142,8 @@ func createSnapshot(filename string, nodes int, services string) (err error) {
|
||||||
return ioutil.WriteFile(filename, jsonsnapshot, 0666)
|
return ioutil.WriteFile(filename, jsonsnapshot, 0666)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// touchPath creates an empty file and all subdirectories
|
||||||
|
// that are missing.
|
||||||
func touchPath(filename string) (string, error) {
|
func touchPath(filename string) (string, error) {
|
||||||
if path.IsAbs(filename) {
|
if path.IsAbs(filename) {
|
||||||
if _, err := os.Stat(filename); err == nil {
|
if _, err := os.Stat(filename); err == nil {
|
||||||
|
|
@ -164,6 +173,5 @@ func touchPath(filename string) (string, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
filename = filePath
|
return filePath, nil
|
||||||
return filename, nil
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,9 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/p2p/simulations"
|
"github.com/ethereum/go-ethereum/p2p/simulations"
|
||||||
)
|
)
|
||||||
|
|
||||||
//TestSnapshotCreate is a high level e2e test that tests for snapshot generation
|
// TestSnapshotCreate is a high level e2e test that tests for snapshot generation.
|
||||||
|
// It runs a few "create" commands with different flag values and loads generated
|
||||||
|
// snapshot files to validate their content.
|
||||||
func TestSnapshotCreate(t *testing.T) {
|
func TestSnapshotCreate(t *testing.T) {
|
||||||
for _, v := range []struct {
|
for _, v := range []struct {
|
||||||
name string
|
name string
|
||||||
|
|
@ -48,8 +50,8 @@ func TestSnapshotCreate(t *testing.T) {
|
||||||
services: "stream,pss,zorglub",
|
services: "stream,pss,zorglub",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "services with " + bzzServiceName,
|
name: "services with bzz",
|
||||||
services: bzzServiceName + ",pss",
|
services: "bzz,pss",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(v.name, func(t *testing.T) {
|
t.Run(v.name, func(t *testing.T) {
|
||||||
|
|
@ -75,8 +77,8 @@ func TestSnapshotCreate(t *testing.T) {
|
||||||
testCmd := runSnapshot(t, append(args, file.Name())...)
|
testCmd := runSnapshot(t, append(args, file.Name())...)
|
||||||
|
|
||||||
testCmd.ExpectExit()
|
testCmd.ExpectExit()
|
||||||
if testCmd.ExitStatus() != 0 {
|
if code := testCmd.ExitStatus(); code != 0 {
|
||||||
t.Fatal("expected exit code 0")
|
t.Fatalf("command exit code %v, expected 0", code)
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := os.Open(file.Name())
|
f, err := os.Open(file.Name())
|
||||||
|
|
@ -117,8 +119,10 @@ func TestSnapshotCreate(t *testing.T) {
|
||||||
if v.services != "" {
|
if v.services != "" {
|
||||||
wantServices = strings.Split(v.services, ",")
|
wantServices = strings.Split(v.services, ",")
|
||||||
} else {
|
} else {
|
||||||
wantServices = []string{bzzServiceName}
|
wantServices = []string{"bzz"}
|
||||||
}
|
}
|
||||||
|
// sort service names so they can be comparable
|
||||||
|
// as strings to every node sorted services
|
||||||
sort.Strings(wantServices)
|
sort.Strings(wantServices)
|
||||||
|
|
||||||
for i, n := range snap.Nodes {
|
for i, n := range snap.Nodes {
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,8 @@ import (
|
||||||
|
|
||||||
var gitCommit string // Git SHA1 commit hash of the release (set via linker flags)
|
var gitCommit string // Git SHA1 commit hash of the release (set via linker flags)
|
||||||
|
|
||||||
const (
|
// default value for "create" command --nodes flag
|
||||||
defaultNodes = 10
|
const defaultNodes = 10
|
||||||
bzzServiceName = "bzz"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := newApp().Run(os.Args)
|
err := newApp().Run(os.Args)
|
||||||
|
|
@ -39,12 +37,15 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// newApp construct a new instance of Swarm Snapshot Utility.
|
||||||
|
// Method Run is called on it in the main function and in tests.
|
||||||
func newApp() (app *cli.App) {
|
func newApp() (app *cli.App) {
|
||||||
app = utils.NewApp(gitCommit, "Swarm Snapshot Utility")
|
app = utils.NewApp(gitCommit, "Swarm Snapshot Utility")
|
||||||
|
|
||||||
app.Name = "swarm-snapshot"
|
app.Name = "swarm-snapshot"
|
||||||
app.Usage = ""
|
app.Usage = ""
|
||||||
|
|
||||||
|
// app flags (for all commands)
|
||||||
app.Flags = []cli.Flag{
|
app.Flags = []cli.Flag{
|
||||||
cli.IntFlag{
|
cli.IntFlag{
|
||||||
Name: "verbosity",
|
Name: "verbosity",
|
||||||
|
|
@ -59,6 +60,9 @@ func newApp() (app *cli.App) {
|
||||||
Aliases: []string{"c"},
|
Aliases: []string{"c"},
|
||||||
Usage: "create a swarm snapshot",
|
Usage: "create a swarm snapshot",
|
||||||
Action: create,
|
Action: create,
|
||||||
|
// Flags only for "create" command.
|
||||||
|
// Allow app flags to be specified after the
|
||||||
|
// command argument.
|
||||||
Flags: append(app.Flags,
|
Flags: append(app.Flags,
|
||||||
cli.IntFlag{
|
cli.IntFlag{
|
||||||
Name: "nodes",
|
Name: "nodes",
|
||||||
|
|
@ -67,7 +71,7 @@ func newApp() (app *cli.App) {
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "services",
|
Name: "services",
|
||||||
Value: bzzServiceName,
|
Value: "bzz",
|
||||||
Usage: "comma separated list of services to boot the nodes with",
|
Usage: "comma separated list of services to boot the nodes with",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
@ -77,6 +81,8 @@ func newApp() (app *cli.App) {
|
||||||
Aliases: []string{"v"},
|
Aliases: []string{"v"},
|
||||||
Usage: "verify a swarm snapshot",
|
Usage: "verify a swarm snapshot",
|
||||||
Action: verify,
|
Action: verify,
|
||||||
|
// Allow app flags to be specified after the
|
||||||
|
// command argument.
|
||||||
Flags: app.Flags,
|
Flags: app.Flags,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import (
|
||||||
cli "gopkg.in/urfave/cli.v1"
|
cli "gopkg.in/urfave/cli.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// verify is used as the entry function for "verify" app command.
|
||||||
func verify(ctx *cli.Context) error {
|
func verify(ctx *cli.Context) error {
|
||||||
log.PrintOrigins(true)
|
log.PrintOrigins(true)
|
||||||
log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(ctx.Int("verbosity")), log.StreamHandler(os.Stdout, log.TerminalFormat(true))))
|
log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(ctx.Int("verbosity")), log.StreamHandler(os.Stdout, log.TerminalFormat(true))))
|
||||||
|
|
@ -42,9 +43,11 @@ func verify(ctx *cli.Context) error {
|
||||||
return verifySnapshot(ctx.Args()[0])
|
return verifySnapshot(ctx.Args()[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// verifySnapshot constructs a simulation, uploads a snapshot from
|
||||||
|
// a file with provided filename and validates that kademlia is healthy.
|
||||||
func verifySnapshot(filename string) (err error) {
|
func verifySnapshot(filename string) (err error) {
|
||||||
sim := simulation.New(map[string]simulation.ServiceFunc{
|
sim := simulation.New(map[string]simulation.ServiceFunc{
|
||||||
bzzServiceName: func(ctx *adapters.ServiceContext, b *sync.Map) (node.Service, func(), error) {
|
"bzz": func(ctx *adapters.ServiceContext, b *sync.Map) (node.Service, func(), error) {
|
||||||
addr := network.NewAddr(ctx.Config.Node())
|
addr := network.NewAddr(ctx.Config.Node())
|
||||||
kad := network.NewKademlia(addr.Over(), network.NewKadParams())
|
kad := network.NewKademlia(addr.Over(), network.NewKadParams())
|
||||||
hp := network.NewHiveParams()
|
hp := network.NewHiveParams()
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TestSnapshotVerify executes "verify" command with a
|
||||||
|
// pregenerated snapshot file that is valid.
|
||||||
func TestSnapshotVerify(t *testing.T) {
|
func TestSnapshotVerify(t *testing.T) {
|
||||||
snap := runSnapshot(t,
|
snap := runSnapshot(t,
|
||||||
"verify",
|
"verify",
|
||||||
|
|
@ -27,7 +29,7 @@ func TestSnapshotVerify(t *testing.T) {
|
||||||
)
|
)
|
||||||
|
|
||||||
snap.ExpectExit()
|
snap.ExpectExit()
|
||||||
if snap.ExitStatus() != 0 {
|
if code := snap.ExitStatus(); code != 0 {
|
||||||
t.Fatal("expected exit code 0")
|
t.Fatalf("command exit code %v, expected 0", code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue