@cryptotaxi247 / kubo / commits / 459e0d537

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 }