fix: routing mock accuracy
routing interface doesn't wait for value to appear in network, but value doesn't appear in network until time as passed License: MIT Signed-off-by: Brian Tiger Chow <brian@perfmode.com>
Brian Tiger Chow committed
Dec 15, 2014 at 20:30 UTC
34b11a3b070d931963e4c307ff97ef74ba1e3343
6 files changed
+84
-17
epictest/addcat_test.go
+4
-1
@@ -104,7 +104,10 @@ func AddCatBytes(data []byte, conf Config) error {
104
105
sessionGenerator := bitswap.NewSessionGenerator(
106
tn.VirtualNetwork(delay.Fixed(conf.NetworkLatency)), // TODO rename VirtualNetwork
107
- mockrouting.NewServerWithDelay(delay.Fixed(conf.RoutingLatency)),
107
+ mockrouting.NewServerWithDelay(mockrouting.DelayConfig{
108
+ Query: delay.Fixed(conf.RoutingLatency),
109
+ ValueVisibility: delay.Fixed(conf.RoutingLatency),
110
+ }),
111
)
112
defer sessionGenerator.Close()
113
routing/mock/client.go
+2
@@ -67,6 +67,8 @@ func (c *client) FindProvidersAsync(ctx context.Context, k u.Key, max int) <-cha
67
return out
68
}
69
70
+// Provide returns once the message is on the network. Value is not necessarily
71
+// visible yet.
72
func (c *client) Provide(_ context.Context, key u.Key) error {
73
return c.server.Announce(c.peer, key)
74
}
routing/mock/interface.go
+16
-4
@@ -28,13 +28,25 @@ type Client interface {
28
29
// NewServer returns a mockrouting Server
30
func NewServer() Server {
31
- return NewServerWithDelay(delay.Fixed(0))
31
+ return NewServerWithDelay(DelayConfig{
32
+ ValueVisibility: delay.Fixed(0),
33
+ Query: delay.Fixed(0),
34
+ })
35
}
36
37
// NewServerWithDelay returns a mockrouting Server with a delay!
35
-func NewServerWithDelay(d delay.D) Server {
38
+func NewServerWithDelay(conf DelayConfig) Server {
39
return &s{
37
- providers: make(map[u.Key]peer.Map),
38
- delay: d,
40
+ providers: make(map[u.Key]map[u.Key]providerRecord),
41
+ delayConf: conf,
42
}
43
}
44
+
45
+type DelayConfig struct {
46
+ // ValueVisibility is the time it takes for a value to be visible in the network
47
+ // FIXME there _must_ be a better term for this
48
+ ValueVisibility delay.D
49
+
50
+ // Query is the time it takes to receive a response from a routing query
51
+ Query delay.D
52
+}
routing/mock/mockrouting_test.go
+36
-1
@@ -3,10 +3,12 @@ package mockrouting
3
import (
4
"bytes"
5
"testing"
6
+ "time"
7
8
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
8
- "github.com/jbenet/go-ipfs/peer"
9
+ peer "github.com/jbenet/go-ipfs/peer"
10
u "github.com/jbenet/go-ipfs/util"
11
+ delay "github.com/jbenet/go-ipfs/util/delay"
12
testutil "github.com/jbenet/go-ipfs/util/testutil"
13
)
14
@@ -129,3 +131,36 @@ func TestCanceledContext(t *testing.T) {
131
t.Fatal("Context cancel had no effect")
132
}
133
}
134
+
135
+func TestValidAfter(t *testing.T) {
136
+
137
+ var p = testutil.NewPeerWithID(peer.ID([]byte("the peer id")))
138
+ var key = u.Key("mock key")
139
+ var ctx = context.Background()
140
+ conf := DelayConfig{
141
+ ValueVisibility: delay.Fixed(1 * time.Hour),
142
+ Query: delay.Fixed(0),
143
+ }
144
+
145
+ rs := NewServerWithDelay(conf)
146
+
147
+ rs.Client(p).Provide(ctx, key)
148
+
149
+ var providers []peer.Peer
150
+ providers, err := rs.Client(p).FindProviders(ctx, key)
151
+ if err != nil {
152
+ t.Fatal(err)
153
+ }
154
+ if len(providers) > 0 {
155
+ t.Fail()
156
+ }
157
+
158
+ conf.ValueVisibility.Set(0)
159
+ providers, err = rs.Client(p).FindProviders(ctx, key)
160
+ if err != nil {
161
+ t.Fatal(err)
162
+ }
163
+ if len(providers) != 1 {
164
+ t.Fail()
165
+ }
166
+}
routing/mock/server.go
+19
-11
@@ -3,11 +3,11 @@ package mockrouting
3
import (
4
"math/rand"
5
"sync"
6
+ "time"
7
8
ds "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-datastore"
9
peer "github.com/jbenet/go-ipfs/peer"
10
u "github.com/jbenet/go-ipfs/util"
10
- delay "github.com/jbenet/go-ipfs/util/delay"
11
)
12
13
// server is the mockrouting.Client's private interface to the routing server
@@ -20,39 +20,47 @@ type server interface {
20
21
// s is an implementation of the private server interface
22
type s struct {
23
- delay delay.D
23
+ delayConf DelayConfig
24
25
lock sync.RWMutex
26
- providers map[u.Key]peer.Map
26
+ providers map[u.Key]map[u.Key]providerRecord
27
}
28
29
-func (rs *s) Announce(p peer.Peer, k u.Key) error {
30
- rs.delay.Wait() // before locking
29
+type providerRecord struct {
30
+ Peer peer.Peer
31
+ Created time.Time
32
+}
33
34
+func (rs *s) Announce(p peer.Peer, k u.Key) error {
35
rs.lock.Lock()
36
defer rs.lock.Unlock()
37
38
_, ok := rs.providers[k]
39
if !ok {
37
- rs.providers[k] = make(peer.Map)
40
+ rs.providers[k] = make(map[u.Key]providerRecord)
41
+ }
42
+ rs.providers[k][p.Key()] = providerRecord{
43
+ Created: time.Now(),
44
+ Peer: p,
45
}
39
- rs.providers[k][p.Key()] = p
46
return nil
47
}
48
49
func (rs *s) Providers(k u.Key) []peer.Peer {
44
- rs.delay.Wait() // before locking
50
+ rs.delayConf.Query.Wait() // before locking
51
52
rs.lock.RLock()
53
defer rs.lock.RUnlock()
54
55
var ret []peer.Peer
50
- peerset, ok := rs.providers[k]
56
+ records, ok := rs.providers[k]
57
if !ok {
58
return ret
59
}
54
- for _, peer := range peerset {
55
- ret = append(ret, peer)
60
+ for _, r := range records {
61
+ if time.Now().Sub(r.Created) > rs.delayConf.ValueVisibility.Get() {
62
+ ret = append(ret, r.Peer)
63
+ }
64
}
65
66
for i := range ret {
util/delay/delay.go
+7
@@ -10,6 +10,7 @@ import (
10
type D interface {
11
Set(time.Duration) time.Duration
12
Wait()
13
+ Get() time.Duration
14
}
15
16
// Fixed returns a delay with fixed latency
@@ -37,3 +38,9 @@ func (d *delay) Wait() {
38
defer d.l.RUnlock()
39
time.Sleep(d.t)
40
}
41
+
42
+func (d *delay) Get() time.Duration {
43
+ d.l.Lock()
44
+ defer d.l.Unlock()
45
+ return d.t
46
+}