ipns TestFastRepublish
Juan Batiz-Benet committed
Oct 8, 2014 at 02:52 UTC
459e0d53737b97a2f3f3ee38982c4adf863791df
3 files changed
+127
-25
fuse/ipns/ipns_test.go
+106
-2
@@ -9,7 +9,8 @@ import (
9
"time"
10
11
fstest "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil"
12
- "github.com/jbenet/go-ipfs/core"
12
+ core "github.com/jbenet/go-ipfs/core"
13
+ u "github.com/jbenet/go-ipfs/util"
14
)
15
16
func randBytes(size int) []byte {
@@ -19,7 +20,10 @@ func randBytes(size int) []byte {
20
}
21
22
func writeFile(t *testing.T, size int, path string) []byte {
22
- data := randBytes(size)
23
+ return writeFileData(t, randBytes(size), path)
24
+}
25
+
26
+func writeFileData(t *testing.T, data []byte, path string) []byte {
27
fi, err := os.Create(path)
28
if err != nil {
29
t.Fatal(err)
@@ -179,6 +183,106 @@ func TestAppendFile(t *testing.T) {
183
}
184
}
185
186
+func TestFastRepublish(t *testing.T) {
187
+
188
+ // make timeout noticeable.
189
+ osrt := shortRepublishTimeout
190
+ shortRepublishTimeout = time.Millisecond * 100
191
+
192
+ olrt := longRepublishTimeout
193
+ longRepublishTimeout = time.Second
194
+
195
+ node, mnt := setupIpnsTest(t, nil)
196
+
197
+ h, err := node.Identity.PrivKey.GetPublic().Hash()
198
+ if err != nil {
199
+ t.Fatal(err)
200
+ }
201
+ pubkeyHash := u.Key(h).Pretty()
202
+
203
+ // set them back
204
+ defer func() {
205
+ shortRepublishTimeout = osrt
206
+ longRepublishTimeout = olrt
207
+ mnt.Close()
208
+ }()
209
+
210
+ closed := make(chan struct{})
211
+ dataA := []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
212
+ dataB := []byte("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")
213
+
214
+ fname := mnt.Dir + "/local/file"
215
+
216
+ // get first resolved hash
217
+ log.Debug("publishing first hash")
218
+ writeFileData(t, dataA, fname) // random
219
+ <-time.After(shortRepublishTimeout * 11 / 10)
220
+ log.Debug("resolving first hash")
221
+ resolvedHash, err := node.Namesys.Resolve(pubkeyHash)
222
+ if err != nil {
223
+ t.Fatal("resolve err:", pubkeyHash, err)
224
+ }
225
+
226
+ // constantly keep writing to the file
227
+ go func() {
228
+ for {
229
+ select {
230
+ case <-closed:
231
+ return
232
+
233
+ case <-time.After(shortRepublishTimeout * 8 / 10):
234
+ writeFileData(t, dataB, fname)
235
+ }
236
+ }
237
+ }()
238
+
239
+ hasPublished := func() bool {
240
+ res, err := node.Namesys.Resolve(pubkeyHash)
241
+ if err != nil {
242
+ t.Fatal("resolve err: %v", err)
243
+ }
244
+ return res != resolvedHash
245
+ }
246
+
247
+ // test things
248
+
249
+ // at this point, should not have written dataA and not have written dataB
250
+ rbuf, err := ioutil.ReadFile(fname)
251
+ if err != nil || !bytes.Equal(rbuf, dataA) {
252
+ t.Fatal("Data inconsistent! %v %v", err, string(rbuf))
253
+ }
254
+
255
+ if hasPublished() {
256
+ t.Fatal("published (wrote)")
257
+ }
258
+
259
+ <-time.After(shortRepublishTimeout * 11 / 10)
260
+
261
+ // at this point, should have written written dataB, but not published it
262
+ rbuf, err = ioutil.ReadFile(fname)
263
+ if err != nil || !bytes.Equal(rbuf, dataB) {
264
+ t.Fatal("Data inconsistent! %v %v", err, string(rbuf))
265
+ }
266
+
267
+ if hasPublished() {
268
+ t.Fatal("published (wrote)")
269
+ }
270
+
271
+ <-time.After(longRepublishTimeout * 11 / 10)
272
+
273
+ // at this point, should have written written dataB, and published it
274
+ rbuf, err = ioutil.ReadFile(fname)
275
+ if err != nil || !bytes.Equal(rbuf, dataB) {
276
+ t.Fatal("Data inconsistent! %v %v", err, string(rbuf))
277
+ }
278
+
279
+ if !hasPublished() {
280
+ t.Fatal("not published")
281
+ }
282
+
283
+ close(closed)
284
+}
285
+
286
// Test writing a medium sized file one byte at a time
287
func TestMultiWrite(t *testing.T) {
288
_, mnt := setupIpnsTest(t, nil)
fuse/ipns/ipns_unix.go
+6
-1
@@ -21,6 +21,11 @@ import (
21
22
var log = u.Logger("ipns")
23
24
+var (
25
+ shortRepublishTimeout = time.Millisecond * 5
26
+ longRepublishTimeout = time.Millisecond * 500
27
+)
28
+
29
// FileSystem is the readwrite IPNS Fuse Filesystem.
30
type FileSystem struct {
31
Ipfs *core.IpfsNode
@@ -71,7 +76,7 @@ func CreateRoot(n *core.IpfsNode, keys []ci.PrivKey, ipfsroot string) (*Root, er
76
nd := new(Node)
77
nd.Ipfs = n
78
nd.key = k
74
- nd.repub = NewRepublisher(nd, time.Millisecond*5, time.Millisecond*500)
79
+ nd.repub = NewRepublisher(nd, shortRepublishTimeout, longRepublishTimeout)
80
81
go nd.repub.Run()
82
fuse/ipns/repub_unix.go
+15
-22
@@ -22,28 +22,21 @@ func (np *Republisher) Run() {
22
for _ = range np.Publish {
23
quick := time.After(np.TimeoutShort)
24
longer := time.After(np.TimeoutLong)
25
- for {
26
- select {
27
- case <-quick:
28
- //Do the publish!
29
- log.Info("Publishing Changes!")
30
- err := np.node.republishRoot()
31
- if err != nil {
32
- log.Critical("republishRoot error: %s", err)
33
- }
34
- goto done
35
- case <-longer:
36
- //Do the publish!
37
- log.Info("Publishing Changes!")
38
- err := np.node.republishRoot()
39
- if err != nil {
40
- log.Critical("republishRoot error: %s", err)
41
- }
42
- goto done
43
- case <-np.Publish:
44
- quick = time.After(np.TimeoutShort)
45
- }
25
+
26
+ wait:
27
+ select {
28
+ case <-quick:
29
+ case <-longer:
30
+ case <-np.Publish:
31
+ quick = time.After(np.TimeoutShort)
32
+ goto wait
33
+ }
34
+
35
+ log.Info("Publishing Changes!")
36
+ err := np.node.republishRoot()
37
+ if err != nil {
38
+ log.Critical("republishRoot error: %s", err)
39
}
47
- done:
40
+
41
}
42
}