notifications_test.go 3.59 KB
Newer Older
1 2 3 4 5 6 7
package notifications

import (
	"bytes"
	"testing"
	"time"

8
	context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
9
	blocks "github.com/jbenet/go-ipfs/blocks"
10 11
	blocksutil "github.com/jbenet/go-ipfs/blocks/blocksutil"
	"github.com/jbenet/go-ipfs/util"
12 13
)

14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
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)
}

39
func TestPublishSubscribe(t *testing.T) {
40
	blockSent := blocks.NewBlock([]byte("Greetings from The Interval"))
41 42 43 44 45

	n := New()
	defer n.Shutdown()
	ch := n.Subscribe(context.Background(), blockSent.Key())

Jeromy's avatar
Jeromy committed
46
	n.Publish(blockSent)
47 48 49 50 51
	blockRecvd, ok := <-ch
	if !ok {
		t.Fail()
	}

Jeromy's avatar
Jeromy committed
52
	assertBlocksEqual(t, blockRecvd, blockSent)
53 54 55

}

Brian Tiger Chow's avatar
Brian Tiger Chow committed
56
func TestSubscribeMany(t *testing.T) {
57 58
	e1 := blocks.NewBlock([]byte("1"))
	e2 := blocks.NewBlock([]byte("2"))
Brian Tiger Chow's avatar
Brian Tiger Chow committed
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78

	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)
}

79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
// 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)
}

103 104 105 106 107 108 109 110 111
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")
	}
}

112 113 114 115 116 117 118
func TestCarryOnWhenDeadlineExpires(t *testing.T) {

	impossibleDeadline := time.Nanosecond
	fastExpiringCtx, _ := context.WithTimeout(context.Background(), impossibleDeadline)

	n := New()
	defer n.Shutdown()
119
	block := blocks.NewBlock([]byte("A Missed Connection"))
120 121 122 123 124
	blockChannel := n.Subscribe(fastExpiringCtx, block.Key())

	assertBlockChannelNil(t, blockChannel)
}

125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
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")
}

Jeromy's avatar
Jeromy committed
153
func assertBlockChannelNil(t *testing.T, blockChannel <-chan *blocks.Block) {
154 155 156 157 158 159
	_, ok := <-blockChannel
	if ok {
		t.Fail()
	}
}

Jeromy's avatar
Jeromy committed
160
func assertBlocksEqual(t *testing.T, a, b *blocks.Block) {
161
	if !bytes.Equal(a.Data, b.Data) {
162
		t.Fatal("blocks aren't equal")
163 164
	}
	if a.Key() != b.Key() {
165
		t.Fatal("block keys aren't equal")
166 167
	}
}