swarm: time for chunk at node in snapshot_sync_test

This commit is contained in:
Fabio Barone 2018-03-02 16:57:22 -05:00
parent 5ca0180e8e
commit 6b45dd22da
6 changed files with 82 additions and 50 deletions

View file

@ -52,6 +52,7 @@ var (
defaultSkipCheck bool defaultSkipCheck bool
waitPeerErrC chan error waitPeerErrC chan error
chunkSize = 4096 chunkSize = 4096
registries map[discover.NodeID]*TestRegistry
) )
var services = adapters.Services{ var services = adapters.Services{
@ -92,7 +93,9 @@ func NewStreamerService(ctx *adapters.ServiceContext) (node.Service, error) {
waitPeerErrC <- waitForPeers(r, 1*time.Second, peerCount(id)) waitPeerErrC <- waitForPeers(r, 1*time.Second, peerCount(id))
}() }()
dpa := storage.NewDPA(storage.NewNetStore(store, nil), storage.NewDPAParams()) dpa := storage.NewDPA(storage.NewNetStore(store, nil), storage.NewDPAParams())
return &TestRegistry{Registry: r, dpa: dpa}, nil testRegistry := &TestRegistry{Registry: r, dpa: dpa}
registries[id] = testRegistry
return testRegistry, nil
} }
//create a local store for the given node //create a local store for the given node
@ -112,12 +115,18 @@ func createTestLocalStorageForId(id discover.NodeID, addr *network.BzzAddr) (sto
return store, nil return store, nil
} }
func datadirsCleanup() {
for _, id := range ids {
os.RemoveAll(datadirs[id])
}
}
//local stores need to be cleaned up after the sim is done //local stores need to be cleaned up after the sim is done
func localStoreCleanup() { func localStoreCleanup() {
log.Info("Cleaning up...") log.Info("Cleaning up...")
for i := 0; i < len(ids); i++ { for _, id := range ids {
stores[ids[i]].Close() registries[id].Close()
os.RemoveAll(datadirs[ids[i]]) stores[id].Close()
} }
log.Info("Local store cleanup done") log.Info("Local store cleanup done")
} }

View file

@ -74,15 +74,6 @@ func (p *Peer) handleRequestSubscription(req *RequestSubscriptionMsg) (err error
return p.streamer.Subscribe(p.ID(), req.Stream, req.History, req.Priority) return p.streamer.Subscribe(p.ID(), req.Stream, req.History, req.Priority)
} }
func (p *Peer) handleRequestSubscription(req *RequestSubscriptionMsg) (err error) {
log.Debug(fmt.Sprintf("handleRequestSubscription: streamer %s to subscribe to %s with stream %s", p.streamer.addr.ID(), p.ID(), req.Stream))
err = p.streamer.Subscribe(p.ID(), req.Stream, req.History, req.Priority)
if err != nil {
return err
}
return nil
}
func (p *Peer) handleSubscribeMsg(req *SubscribeMsg) (err error) { func (p *Peer) handleSubscribeMsg(req *SubscribeMsg) (err error) {
defer func() { defer func() {
if err != nil { if err != nil {

View file

@ -33,7 +33,7 @@ import (
"github.com/ethereum/go-ethereum/p2p/simulations/adapters" "github.com/ethereum/go-ethereum/p2p/simulations/adapters"
"github.com/ethereum/go-ethereum/pot" "github.com/ethereum/go-ethereum/pot"
"github.com/ethereum/go-ethereum/swarm/network" "github.com/ethereum/go-ethereum/swarm/network"
streamTesting "github.com/ethereum/go-ethereum/swarm/network/stream/testing" //streamTesting "github.com/ethereum/go-ethereum/swarm/network/stream/testing"
"github.com/ethereum/go-ethereum/swarm/storage" "github.com/ethereum/go-ethereum/swarm/storage"
) )
@ -47,6 +47,8 @@ var (
datadirs map[discover.NodeID]string datadirs map[discover.NodeID]string
conf *synctestConfig conf *synctestConfig
ppmap map[discover.NodeID]*network.PeerPot ppmap map[discover.NodeID]*network.PeerPot
printed bool
) )
type synctestConfig struct { type synctestConfig struct {
@ -84,6 +86,8 @@ func initSyncTest() {
datadirs = make(map[discover.NodeID]string) datadirs = make(map[discover.NodeID]string)
//deliveries for each node //deliveries for each node
deliveries = make(map[discover.NodeID]*Delivery) deliveries = make(map[discover.NodeID]*Delivery)
//registries, map of discover.NodeID to its streamer
registries = make(map[discover.NodeID]*TestRegistry)
//channel to wait for peers connected //channel to wait for peers connected
waitPeerErrC = make(chan error) waitPeerErrC = make(chan error)
@ -194,12 +198,32 @@ func runSyncTest(chunkCount int, nodeCount int) error {
//map of overlay address to discover ID //map of overlay address to discover ID
conf.addrToIdMap = make(map[string]discover.NodeID) conf.addrToIdMap = make(map[string]discover.NodeID)
//First load the snapshot from the file //First load the snapshot from the file
var actionTicker *time.Ticker
var timingTicker *time.Ticker
trigger := make(chan discover.NodeID)
// channel to signal simulation initialisation with action call complete
// or node disconnections
disconnectC := make(chan error)
quitC := make(chan struct{})
net, err := initNetWithSnapshot(nodeCount) net, err := initNetWithSnapshot(nodeCount)
if err != nil { if err != nil {
return err return err
} }
defer net.Shutdown() cleanup := func() {
timingTicker.Stop()
actionTicker.Stop()
//close(trigger)
close(quitC)
close(disconnectC)
close(waitPeerErrC)
//after the test, clean up local stores initialized with createLocalStoreForId
localStoreCleanup()
//shutdown the snapshot network
net.Shutdown()
//datadirsCleanup()
}
defer cleanup()
//get the nodes of the network //get the nodes of the network
nodes := net.GetNodes() nodes := net.GetNodes()
//select one index at random... //select one index at random...
@ -226,13 +250,6 @@ func runSyncTest(chunkCount int, nodeCount int) error {
log.Info("Test config successfully initialized") log.Info("Test config successfully initialized")
ppmap = network.NewPeerPot(testMinProxBinSize, ids, conf.addrs) ppmap = network.NewPeerPot(testMinProxBinSize, ids, conf.addrs)
// channel to signal simulation initialisation with action call complete
// or node disconnections
disconnectC := make(chan error)
quitC := make(chan struct{})
//after the test, clean up local stores initialized with createLocalStoreForId
defer localStoreCleanup()
//define the action to be performed before the test checks: start syncing //define the action to be performed before the test checks: start syncing
action := func(ctx context.Context) error { action := func(ctx context.Context) error {
@ -286,10 +303,10 @@ func runSyncTest(chunkCount int, nodeCount int) error {
log.Debug(kt) log.Debug(kt)
} }
} }
err = streamTesting.WatchDisconnections(id, client, disconnectC, quitC) //err = streamTesting.WatchDisconnections(id, client, disconnectC, quitC)
if err != nil { //if err != nil {
return err // return err
} //}
err = client.CallContext(ctx, nil, "stream_startSyncing") err = client.CallContext(ctx, nil, "stream_startSyncing")
if err != nil { if err != nil {
return err return err
@ -309,10 +326,19 @@ func runSyncTest(chunkCount int, nodeCount int) error {
//finally map chunks to the closest addresses //finally map chunks to the closest addresses
mapKeysToNodes(conf) mapKeysToNodes(conf)
//periodically check if chunks have arrived at nodes
actionTicker = time.NewTicker(time.Second / 100)
go func() {
startTime = time.Now()
for range actionTicker.C {
checkChunkIsAtNode(conf)
}
}()
log.Info("Action terminated")
return nil return nil
} }
trigger := make(chan discover.NodeID)
//check defines what will be checked during the test //check defines what will be checked during the test
check := func(ctx context.Context, id discover.NodeID) (bool, error) { check := func(ctx context.Context, id discover.NodeID) (bool, error) {
select { select {
@ -323,7 +349,6 @@ func runSyncTest(chunkCount int, nodeCount int) error {
return false, ctx.Err() return false, ctx.Err()
default: default:
} }
log.Trace(fmt.Sprintf("Checking node: %s", id)) log.Trace(fmt.Sprintf("Checking node: %s", id))
//select the local store for the given node //select the local store for the given node
lstore := stores[id] lstore := stores[id]
@ -353,25 +378,16 @@ func runSyncTest(chunkCount int, nodeCount int) error {
ctx, cancel := context.WithTimeout(context.Background(), timeout) ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel() defer cancel()
timingTicker = time.NewTicker(time.Second * 1)
//for each tick, run the checks on all nodes //for each tick, run the checks on all nodes
go func() { go func() {
ticker := time.NewTicker(time.Second * 1) for range timingTicker.C {
for range ticker.C {
for i := 0; i < len(ids); i++ { for i := 0; i < len(ids); i++ {
log.Trace(fmt.Sprintf("triggering step %d, id %s", i, ids[i])) log.Trace(fmt.Sprintf("triggering step %d, id %s", i, ids[i]))
trigger <- ids[i] trigger <- ids[i]
} }
} }
}() }()
/*
go func() {
startTime = time.Now()
ticker := time.NewTicker(time.Second / 10)
for range ticker.C {
checkChunkIsAtNode(conf)
}
}()
*/
log.Info("Starting simulation run...") log.Info("Starting simulation run...")
//run the simulation //run the simulation
@ -383,11 +399,9 @@ func runSyncTest(chunkCount int, nodeCount int) error {
Check: check, Check: check,
}, },
}) })
close(quitC)
if result.Error != nil { if result.Error != nil {
return result.Error return result.Error
} }
log.Info("Simulation terminated") log.Info("Simulation terminated")
return nil return nil
} }
@ -432,7 +446,6 @@ func (r *TestRegistry) StartSyncing(ctx context.Context) error {
//iterate over each bin and solicit needed subscription to bins //iterate over each bin and solicit needed subscription to bins
kad.EachBin(r.addr.Over(), pof, 0, func(po, size int, f func(func(val pot.Val, i int) bool) bool) bool { kad.EachBin(r.addr.Over(), pof, 0, func(po, size int, f func(func(val pot.Val, i int) bool) bool) bool {
//identify begin and start index of the bin(s) we want to subscribe to //identify begin and start index of the bin(s) we want to subscribe to
if po < kadDepth { if po < kadDepth {
//not nn //not nn
@ -471,28 +484,45 @@ func (r *TestRegistry) StartSyncing(ctx context.Context) error {
return nil return nil
} }
//periodically check if chunks have arrived at nodes
func checkChunkIsAtNode(conf *synctestConfig) { func checkChunkIsAtNode(conf *synctestConfig) {
allOk := true allOk := true
if printed {
return
}
//for every chunk, get the array of nodes it should have arrived to
for chunk, nodes := range conf.chunksToNodesMap { for chunk, nodes := range conf.chunksToNodesMap {
//for every of those nodes
for _, node := range nodes { for _, node := range nodes {
//check that the chunk is in that localstore
if ok, _ := stores[conf.addrToIdMap[string(conf.addrs[node])]].Get([]byte(chunk)); ok != nil { if ok, _ := stores[conf.addrToIdMap[string(conf.addrs[node])]].Get([]byte(chunk)); ok != nil {
//if it is there, write the amount of time passed in the retrievalMap
//first create the map for the chunk if it is not there yet
if len(conf.retrievalMap[chunk]) == 0 { if len(conf.retrievalMap[chunk]) == 0 {
conf.retrievalMap[chunk] = make(map[string]time.Duration) conf.retrievalMap[chunk] = make(map[string]time.Duration)
} }
//if the time value for the chunk at this node has not been recorded yet...
if _, ok := conf.retrievalMap[chunk][string(conf.addrs[node])]; !ok {
//...record it
conf.retrievalMap[chunk][string(conf.addrs[node])] = time.Since(startTime) conf.retrievalMap[chunk][string(conf.addrs[node])] = time.Since(startTime)
} }
} else {
allOk = false
}
//if one of the chunks hasn't arrived yet, don't print
if conf.retrievalMap[chunk][string(conf.addrs[node])] == 0 { if conf.retrievalMap[chunk][string(conf.addrs[node])] == 0 {
allOk = false allOk = false
} }
} }
} }
if allOk { if allOk && !printed {
log.Info("All chunks arrived at destination") log.Info("All chunks arrived at destination")
for ch, n := range conf.retrievalMap { for ch, n := range conf.retrievalMap {
for a, t := range n { for a, t := range n {
log.Info(fmt.Sprintf("Chunk %s at node %s took %v ms", string(ch), string(a), t.Seconds()*1e3)) log.Info(fmt.Sprintf("Chunk %v at node %s took %v ms", storage.Key([]byte((ch))).String()[:8], conf.addrToIdMap[string(a)].String()[0:8], t.Seconds()*1e3))
} }
} }
printed = true
} }
} }
@ -529,7 +559,7 @@ func mapKeysToNodes(conf *synctestConfig) {
} }
return true return true
}) })
kmap[conf.chunks[i].String()] = nns kmap[string(conf.chunks[i])] = nns
//log.Debug(fmt.Sprintf("Length for id %s: %d",ids[i],len(kmap[ids[i]]))) //log.Debug(fmt.Sprintf("Length for id %s: %d",ids[i],len(kmap[ids[i]])))
} }
if log.Lvl(*loglevel) == log.LvlTrace { if log.Lvl(*loglevel) == log.LvlTrace {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -228,7 +228,9 @@ func WatchDisconnections(id discover.NodeID, client *rpc.Client, errc chan error
case <-quitC: case <-quitC:
return return
case e := <-events: case e := <-events:
if e.Type == p2p.PeerEventTypeDrop {
errc <- fmt.Errorf("peerEvent for node %v: %v", id, e) errc <- fmt.Errorf("peerEvent for node %v: %v", id, e)
}
case err := <-sub.Err(): case err := <-sub.Err():
if err != nil { if err != nil {
errc <- fmt.Errorf("error getting peer events for node %v: %v", id, err) errc <- fmt.Errorf("error getting peer events for node %v: %v", id, err)