mirror of
https://github.com/ipfs/kubo.git
synced 2026-03-10 18:57:57 +08:00
- updated go-ctxgroup and goprocess ctxgroup: AddChildGroup was changed to AddChild. Used in two files: - p2p/net/mock/mock_net.go - routing/dht/dht.go - updated context from hg repo to git prev. commit in hg was ad01a6fcc8a19d3a4478c836895ffe883bd2ceab. (context: make parentCancelCtx iterative) represents commit 84f8955a887232b6308d79c68b8db44f64df455c in git repo - updated context to master (b6fdb7d8a4ccefede406f8fe0f017fb58265054c) Aaron Jacobs (2): net/context: Don't accept a context in the DoSomethingSlow example. context: Be clear that users must cancel the result of WithCancel. Andrew Gerrand (1): go.net: use golang.org/x/... import paths Bryan C. Mills (1): net/context: Don't leak goroutines in Done example. Damien Neil (1): context: fix removal of cancelled timer contexts from parent David Symonds (2): context: Fix WithValue example code. net: add import comments. Sameer Ajmani (1): context: fix TestAllocs to account for ints in interfaces
168 lines
3.6 KiB
Go
168 lines
3.6 KiB
Go
package notifications
|
|
|
|
import (
|
|
"bytes"
|
|
"testing"
|
|
"time"
|
|
|
|
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
|
|
blocks "github.com/jbenet/go-ipfs/blocks"
|
|
blocksutil "github.com/jbenet/go-ipfs/blocks/blocksutil"
|
|
"github.com/jbenet/go-ipfs/util"
|
|
)
|
|
|
|
func TestDuplicates(t *testing.T) {
|
|
b1 := blocks.NewBlock([]byte("1"))
|
|
b2 := blocks.NewBlock([]byte("2"))
|
|
|
|
n := New()
|
|
defer n.Shutdown()
|
|
ch := n.Subscribe(context.Background(), b1.Key(), b2.Key())
|
|
|
|
n.Publish(b1)
|
|
blockRecvd, ok := <-ch
|
|
if !ok {
|
|
t.Fail()
|
|
}
|
|
assertBlocksEqual(t, b1, blockRecvd)
|
|
|
|
n.Publish(b1) // ignored duplicate
|
|
|
|
n.Publish(b2)
|
|
blockRecvd, ok = <-ch
|
|
if !ok {
|
|
t.Fail()
|
|
}
|
|
assertBlocksEqual(t, b2, blockRecvd)
|
|
}
|
|
|
|
func TestPublishSubscribe(t *testing.T) {
|
|
blockSent := blocks.NewBlock([]byte("Greetings from The Interval"))
|
|
|
|
n := New()
|
|
defer n.Shutdown()
|
|
ch := n.Subscribe(context.Background(), blockSent.Key())
|
|
|
|
n.Publish(blockSent)
|
|
blockRecvd, ok := <-ch
|
|
if !ok {
|
|
t.Fail()
|
|
}
|
|
|
|
assertBlocksEqual(t, blockRecvd, blockSent)
|
|
|
|
}
|
|
|
|
func TestSubscribeMany(t *testing.T) {
|
|
e1 := blocks.NewBlock([]byte("1"))
|
|
e2 := blocks.NewBlock([]byte("2"))
|
|
|
|
n := New()
|
|
defer n.Shutdown()
|
|
ch := n.Subscribe(context.Background(), e1.Key(), e2.Key())
|
|
|
|
n.Publish(e1)
|
|
r1, ok := <-ch
|
|
if !ok {
|
|
t.Fatal("didn't receive first expected block")
|
|
}
|
|
assertBlocksEqual(t, e1, r1)
|
|
|
|
n.Publish(e2)
|
|
r2, ok := <-ch
|
|
if !ok {
|
|
t.Fatal("didn't receive second expected block")
|
|
}
|
|
assertBlocksEqual(t, e2, r2)
|
|
}
|
|
|
|
// TestDuplicateSubscribe tests a scenario where a given block
|
|
// would be requested twice at the same time.
|
|
func TestDuplicateSubscribe(t *testing.T) {
|
|
e1 := blocks.NewBlock([]byte("1"))
|
|
|
|
n := New()
|
|
defer n.Shutdown()
|
|
ch1 := n.Subscribe(context.Background(), e1.Key())
|
|
ch2 := n.Subscribe(context.Background(), e1.Key())
|
|
|
|
n.Publish(e1)
|
|
r1, ok := <-ch1
|
|
if !ok {
|
|
t.Fatal("didn't receive first expected block")
|
|
}
|
|
assertBlocksEqual(t, e1, r1)
|
|
|
|
r2, ok := <-ch2
|
|
if !ok {
|
|
t.Fatal("didn't receive second expected block")
|
|
}
|
|
assertBlocksEqual(t, e1, r2)
|
|
}
|
|
|
|
func TestSubscribeIsANoopWhenCalledWithNoKeys(t *testing.T) {
|
|
n := New()
|
|
defer n.Shutdown()
|
|
ch := n.Subscribe(context.TODO()) // no keys provided
|
|
if _, ok := <-ch; ok {
|
|
t.Fatal("should be closed if no keys provided")
|
|
}
|
|
}
|
|
|
|
func TestCarryOnWhenDeadlineExpires(t *testing.T) {
|
|
|
|
impossibleDeadline := time.Nanosecond
|
|
fastExpiringCtx, _ := context.WithTimeout(context.Background(), impossibleDeadline)
|
|
|
|
n := New()
|
|
defer n.Shutdown()
|
|
block := blocks.NewBlock([]byte("A Missed Connection"))
|
|
blockChannel := n.Subscribe(fastExpiringCtx, block.Key())
|
|
|
|
assertBlockChannelNil(t, blockChannel)
|
|
}
|
|
|
|
func TestDoesNotDeadLockIfContextCancelledBeforePublish(t *testing.T) {
|
|
|
|
g := blocksutil.NewBlockGenerator()
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
n := New()
|
|
defer n.Shutdown()
|
|
|
|
t.Log("generate a large number of blocks. exceed default buffer")
|
|
bs := g.Blocks(1000)
|
|
ks := func() []util.Key {
|
|
var keys []util.Key
|
|
for _, b := range bs {
|
|
keys = append(keys, b.Key())
|
|
}
|
|
return keys
|
|
}()
|
|
|
|
_ = n.Subscribe(ctx, ks...) // ignore received channel
|
|
|
|
t.Log("cancel context before any blocks published")
|
|
cancel()
|
|
for _, b := range bs {
|
|
n.Publish(b)
|
|
}
|
|
|
|
t.Log("publishing the large number of blocks to the ignored channel must not deadlock")
|
|
}
|
|
|
|
func assertBlockChannelNil(t *testing.T, blockChannel <-chan *blocks.Block) {
|
|
_, ok := <-blockChannel
|
|
if ok {
|
|
t.Fail()
|
|
}
|
|
}
|
|
|
|
func assertBlocksEqual(t *testing.T, a, b *blocks.Block) {
|
|
if !bytes.Equal(a.Data, b.Data) {
|
|
t.Fatal("blocks aren't equal")
|
|
}
|
|
if a.Key() != b.Key() {
|
|
t.Fatal("block keys aren't equal")
|
|
}
|
|
}
|