centralized_test.go 4.21 KB
Newer Older
Brian Tiger Chow's avatar
Brian Tiger Chow committed
1
package mockrouting
2 3

import (
4
	"context"
5
	"testing"
Brian Tiger Chow's avatar
Brian Tiger Chow committed
6
	"time"
7

8
	delay "github.com/ipfs/go-ipfs/thirdparty/delay"
Steven Allen's avatar
Steven Allen committed
9
	"gx/ipfs/QmVvkK7s5imCiq3JVbL3pGfnhcCnf3LrFJPF4GE2sAoGZf/go-testutil"
10

Steven Allen's avatar
Steven Allen committed
11
	u "gx/ipfs/QmNiJuT8Ja3hMVpBHXv3Q6dwmperaQ6JjLtpMQgMCD7xvx/go-ipfs-util"
Steven Allen's avatar
Steven Allen committed
12
	pstore "gx/ipfs/QmXauCuJzmzapetmC6W4TuDJLL1yFFrVzSHoWv8YdbmnxH/go-libp2p-peerstore"
Steven Allen's avatar
Steven Allen committed
13
	cid "gx/ipfs/QmcZfnkapfECQGcLZaf9B79NRg7cRa9EnZh4LSbkCzwNvY/go-cid"
14 15 16 17
)

func TestKeyNotFound(t *testing.T) {

18
	var pi = testutil.RandIdentityOrFatal(t)
19
	var key = cid.NewCidV0(u.Hash([]byte("mock key")))
Brian Tiger Chow's avatar
Brian Tiger Chow committed
20
	var ctx = context.Background()
21

Brian Tiger Chow's avatar
Brian Tiger Chow committed
22
	rs := NewServer()
23
	providers := rs.Client(pi).FindProvidersAsync(ctx, key, 10)
Brian Tiger Chow's avatar
Brian Tiger Chow committed
24 25 26
	_, ok := <-providers
	if ok {
		t.Fatal("should be closed")
27 28 29 30
	}
}

func TestClientFindProviders(t *testing.T) {
31
	pi := testutil.RandIdentityOrFatal(t)
Brian Tiger Chow's avatar
Brian Tiger Chow committed
32
	rs := NewServer()
33
	client := rs.Client(pi)
34

35
	k := cid.NewCidV0(u.Hash([]byte("hello")))
36
	err := client.Provide(context.Background(), k, true)
37 38 39
	if err != nil {
		t.Fatal(err)
	}
40 41 42

	// This is bad... but simulating networks is hard
	time.Sleep(time.Millisecond * 300)
43 44
	max := 100

45
	providersFromClient := client.FindProvidersAsync(context.Background(), k, max)
46
	isInClient := false
47
	for pi := range providersFromClient {
48
		if pi.ID == pi.ID { // <-- typo?
49 50 51 52 53 54 55 56 57
			isInClient = true
		}
	}
	if !isInClient {
		t.Fatal("Despite client providing key, client didn't receive peer when finding providers")
	}
}

func TestClientOverMax(t *testing.T) {
Brian Tiger Chow's avatar
Brian Tiger Chow committed
58
	rs := NewServer()
59
	k := cid.NewCidV0(u.Hash([]byte("hello")))
60 61
	numProvidersForHelloKey := 100
	for i := 0; i < numProvidersForHelloKey; i++ {
62
		pi := testutil.RandIdentityOrFatal(t)
63
		err := rs.Client(pi).Provide(context.Background(), k, true)
64 65 66 67 68 69
		if err != nil {
			t.Fatal(err)
		}
	}

	max := 10
70
	pi := testutil.RandIdentityOrFatal(t)
71
	client := rs.Client(pi)
72 73 74

	providersFromClient := client.FindProvidersAsync(context.Background(), k, max)
	i := 0
75
	for range providersFromClient {
76 77 78 79 80 81 82 83 84
		i++
	}
	if i != max {
		t.Fatal("Too many providers returned")
	}
}

// TODO does dht ensure won't receive self as a provider? probably not.
func TestCanceledContext(t *testing.T) {
Brian Tiger Chow's avatar
Brian Tiger Chow committed
85
	rs := NewServer()
86
	k := cid.NewCidV0(u.Hash([]byte("hello")))
87

88 89 90 91 92 93
	// avoid leaking goroutine, without using the context to signal
	// (we want the goroutine to keep trying to publish on a
	// cancelled context until we've tested it doesnt do anything.)
	done := make(chan struct{})
	defer func() { done <- struct{}{} }()

94 95 96 97
	t.Log("async'ly announce infinite stream of providers for key")
	i := 0
	go func() { // infinite stream
		for {
98 99 100 101 102 103 104
			select {
			case <-done:
				t.Log("exiting async worker")
				return
			default:
			}

105
			pi, err := testutil.RandIdentity()
Brian Tiger Chow's avatar
Brian Tiger Chow committed
106 107 108
			if err != nil {
				t.Error(err)
			}
109
			err = rs.Client(pi).Provide(context.Background(), k, true)
110
			if err != nil {
111
				t.Error(err)
112 113 114 115 116
			}
			i++
		}
	}()

117
	local := testutil.RandIdentityOrFatal(t)
118 119 120 121 122 123 124 125 126 127 128 129 130
	client := rs.Client(local)

	t.Log("warning: max is finite so this test is non-deterministic")
	t.Log("context cancellation could simply take lower priority")
	t.Log("and result in receiving the max number of results")
	max := 1000

	t.Log("cancel the context before consuming")
	ctx, cancelFunc := context.WithCancel(context.Background())
	cancelFunc()
	providers := client.FindProvidersAsync(ctx, k, max)

	numProvidersReturned := 0
131
	for range providers {
132 133 134 135 136 137 138 139
		numProvidersReturned++
	}
	t.Log(numProvidersReturned)

	if numProvidersReturned == max {
		t.Fatal("Context cancel had no effect")
	}
}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
140 141

func TestValidAfter(t *testing.T) {
142 143
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
Brian Tiger Chow's avatar
Brian Tiger Chow committed
144

145
	pi := testutil.RandIdentityOrFatal(t)
146
	key := cid.NewCidV0(u.Hash([]byte("mock key")))
Brian Tiger Chow's avatar
Brian Tiger Chow committed
147 148 149 150 151 152 153
	conf := DelayConfig{
		ValueVisibility: delay.Fixed(1 * time.Hour),
		Query:           delay.Fixed(0),
	}

	rs := NewServerWithDelay(conf)

154
	rs.Client(pi).Provide(ctx, key, true)
Brian Tiger Chow's avatar
Brian Tiger Chow committed
155

Jeromy's avatar
Jeromy committed
156
	var providers []pstore.PeerInfo
157 158 159 160
	max := 100
	providersChan := rs.Client(pi).FindProvidersAsync(ctx, key, max)
	for p := range providersChan {
		providers = append(providers, p)
Brian Tiger Chow's avatar
Brian Tiger Chow committed
161 162 163 164 165 166
	}
	if len(providers) > 0 {
		t.Fail()
	}

	conf.ValueVisibility.Set(0)
167
	providersChan = rs.Client(pi).FindProvidersAsync(ctx, key, max)
168
	t.Log("providers", providers)
169 170 171
	for p := range providersChan {
		providers = append(providers, p)
	}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
172 173 174 175
	if len(providers) != 1 {
		t.Fail()
	}
}