provider_test.go 3.19 KB
Newer Older
1
package simple_test
Erik Ingenito's avatar
Erik Ingenito committed
2 3 4 5 6 7

import (
	"context"
	"math/rand"
	"testing"
	"time"
8 9 10 11

	cid "github.com/ipfs/go-cid"
	datastore "github.com/ipfs/go-datastore"
	sync "github.com/ipfs/go-datastore/sync"
Erik Ingenito's avatar
Gofmt  
Erik Ingenito committed
12
	blocksutil "github.com/ipfs/go-ipfs-blocksutil"
Raúl Kripalani's avatar
Raúl Kripalani committed
13
	peer "github.com/libp2p/go-libp2p-core/peer"
14

Michael Avila's avatar
Michael Avila committed
15
	q "github.com/ipfs/go-ipfs-provider/queue"
16

Michael Avila's avatar
Michael Avila committed
17
	. "github.com/ipfs/go-ipfs-provider/simple"
Erik Ingenito's avatar
Erik Ingenito committed
18 19 20 21 22 23 24 25
)

var blockGenerator = blocksutil.NewBlockGenerator()

type mockRouting struct {
	provided chan cid.Cid
}

Erik Ingenito's avatar
Erik Ingenito committed
26
func (r *mockRouting) Provide(ctx context.Context, cid cid.Cid, recursive bool) error {
Michael Avila's avatar
Michael Avila committed
27 28 29 30 31
	select {
	case r.provided <- cid:
	case <-ctx.Done():
		panic("context cancelled, but shouldn't have")
	}
Erik Ingenito's avatar
Erik Ingenito committed
32 33 34
	return nil
}

Raúl Kripalani's avatar
Raúl Kripalani committed
35
func (r *mockRouting) FindProvidersAsync(ctx context.Context, cid cid.Cid, timeout int) <-chan peer.AddrInfo {
Erik Ingenito's avatar
Erik Ingenito committed
36 37 38
	return nil
}

Erik Ingenito's avatar
Erik Ingenito committed
39 40 41 42 43 44 45 46
func mockContentRouting() *mockRouting {
	r := mockRouting{}
	r.provided = make(chan cid.Cid)
	return &r
}

func TestAnnouncement(t *testing.T) {
	ctx := context.Background()
47
	defer ctx.Done()
Erik Ingenito's avatar
Erik Ingenito committed
48

49
	ds := sync.MutexWrap(datastore.NewMapDatastore())
50
	queue, err := q.NewQueue(ctx, "test", ds)
Erik Ingenito's avatar
Erik Ingenito committed
51 52 53 54 55 56
	if err != nil {
		t.Fatal(err)
	}

	r := mockContentRouting()

57 58
	prov := NewProvider(ctx, queue, r)
	prov.Run()
Erik Ingenito's avatar
Erik Ingenito committed
59 60 61

	cids := cid.NewSet()

62
	for i := 0; i < 100; i++ {
Erik Ingenito's avatar
Erik Ingenito committed
63 64 65 66 67 68
		c := blockGenerator.Next().Cid()
		cids.Add(c)
	}

	go func() {
		for _, c := range cids.Keys() {
69
			err = prov.Provide(c)
Erik Ingenito's avatar
Erik Ingenito committed
70 71 72 73 74 75 76 77
			// A little goroutine stirring to exercise some different states
			r := rand.Intn(10)
			time.Sleep(time.Microsecond * time.Duration(r))
		}
	}()

	for cids.Len() > 0 {
		select {
Erik Ingenito's avatar
Gofmt  
Erik Ingenito committed
78 79 80 81 82 83 84
		case cp := <-r.provided:
			if !cids.Has(cp) {
				t.Fatal("Wrong CID provided")
			}
			cids.Remove(cp)
		case <-time.After(time.Second * 5):
			t.Fatal("Timeout waiting for cids to be provided.")
Erik Ingenito's avatar
Erik Ingenito committed
85 86
		}
	}
Steven Allen's avatar
Steven Allen committed
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
	prov.Close()

	select {
	case cp := <-r.provided:
		t.Fatal("did not expect to provide CID: ", cp)
	case <-time.After(time.Second * 1):
	}
}

func TestClose(t *testing.T) {
	ctx := context.Background()
	defer ctx.Done()

	ds := sync.MutexWrap(datastore.NewMapDatastore())
	queue, err := q.NewQueue(ctx, "test", ds)
	if err != nil {
		t.Fatal(err)
	}

	r := mockContentRouting()

	prov := NewProvider(ctx, queue, r)
	prov.Run()

	prov.Close()

	select {
	case cp := <-r.provided:
		t.Fatal("did not expect to provide anything, provided: ", cp)
	case <-time.After(time.Second * 1):
	}
Erik Ingenito's avatar
Erik Ingenito committed
118
}
Michael Avila's avatar
Michael Avila committed
119 120 121 122 123 124 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 153 154 155 156 157 158 159 160 161 162

func TestAnnouncementTimeout(t *testing.T) {
	ctx := context.Background()
	defer ctx.Done()

	ds := sync.MutexWrap(datastore.NewMapDatastore())
	queue, err := q.NewQueue(ctx, "test", ds)
	if err != nil {
		t.Fatal(err)
	}

	r := mockContentRouting()

	prov := NewProvider(ctx, queue, r, WithTimeout(1*time.Second))
	prov.Run()

	cids := cid.NewSet()

	for i := 0; i < 100; i++ {
		c := blockGenerator.Next().Cid()
		cids.Add(c)
	}

	go func() {
		for _, c := range cids.Keys() {
			err = prov.Provide(c)
			// A little goroutine stirring to exercise some different states
			r := rand.Intn(10)
			time.Sleep(time.Microsecond * time.Duration(r))
		}
	}()

	for cids.Len() > 0 {
		select {
		case cp := <-r.provided:
			if !cids.Has(cp) {
				t.Fatal("Wrong CID provided")
			}
			cids.Remove(cp)
		case <-time.After(time.Second * 5):
			t.Fatal("Timeout waiting for cids to be provided.")
		}
	}
}