Skip to content

Commit 49d524a

Browse files
committed
routing/http/server: put smoke tests
1 parent fd4b351 commit 49d524a

File tree

1 file changed

+200
-22
lines changed

1 file changed

+200
-22
lines changed

routing/http/server/server_test.go

Lines changed: 200 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"context"
66
"crypto/rand"
7+
"encoding/json"
78
"io"
89
"net/http"
910
"net/http/httptest"
@@ -14,10 +15,13 @@ import (
1415
"github.com/ipfs/boxo/path"
1516
"github.com/ipfs/boxo/routing/http/types"
1617
"github.com/ipfs/boxo/routing/http/types/iter"
18+
tjson "github.com/ipfs/boxo/routing/http/types/json"
1719
"github.com/ipfs/go-cid"
1820
"github.com/libp2p/go-libp2p/core/crypto"
1921
"github.com/libp2p/go-libp2p/core/peer"
2022
b58 "github.com/mr-tron/base58/base58"
23+
"github.com/multiformats/go-multiaddr"
24+
"github.com/multiformats/go-multihash"
2125
"github.com/stretchr/testify/mock"
2226
"github.com/stretchr/testify/require"
2327
)
@@ -66,26 +70,35 @@ func makePeerID(t *testing.T) (crypto.PrivKey, peer.ID) {
6670
return sk, pid
6771
}
6872

69-
func TestProviders(t *testing.T) {
70-
pidStr := "12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vn"
71-
pid2Str := "12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vz"
72-
cidStr := "bafkreifjjcie6lypi6ny7amxnfftagclbuxndqonfipmb64f2km2devei4"
73-
74-
pid, err := peer.Decode(pidStr)
73+
func makeCID(t *testing.T) cid.Cid {
74+
buf := make([]byte, 63)
75+
_, err := rand.Read(buf)
7576
require.NoError(t, err)
76-
pid2, err := peer.Decode(pid2Str)
77+
mh, err := multihash.Encode(buf, multihash.SHA2_256)
7778
require.NoError(t, err)
79+
c := cid.NewCidV1(0, mh)
80+
return c
81+
}
7882

79-
cid, err := cid.Decode(cidStr)
80-
require.NoError(t, err)
83+
func TestProviders(t *testing.T) {
84+
// Prepare some variables common to all tests.
85+
sk1, pid1 := makePeerID(t)
86+
pid1Str := pid1.String()
8187

82-
runTest := func(t *testing.T, contentType string, expectedStream bool, expectedBody string) {
88+
sk2, pid2 := makePeerID(t)
89+
pid2Str := pid2.String()
90+
91+
cid1 := makeCID(t)
92+
cid1Str := cid1.String()
93+
94+
// GET Tests
95+
runGetTest := func(t *testing.T, contentType string, expectedStream bool, expectedBody string) {
8396
t.Parallel()
8497

8598
results := iter.FromSlice([]iter.Result[types.Record]{
8699
{Val: &types.PeerRecord{
87100
Schema: types.SchemaPeer,
88-
ID: &pid,
101+
ID: &pid1,
89102
Protocols: []string{"transport-bitswap"},
90103
Addrs: []types.Multiaddr{},
91104
}},
@@ -105,8 +118,8 @@ func TestProviders(t *testing.T) {
105118
if expectedStream {
106119
limit = DefaultStreamingRecordsLimit
107120
}
108-
router.On("FindProviders", mock.Anything, cid, limit).Return(results, nil)
109-
urlStr := serverAddr + "/routing/v1/providers/" + cidStr
121+
router.On("FindProviders", mock.Anything, cid1, limit).Return(results, nil)
122+
urlStr := serverAddr + "/routing/v1/providers/" + cid1Str
110123

111124
req, err := http.NewRequest(http.MethodGet, urlStr, nil)
112125
require.NoError(t, err)
@@ -124,17 +137,100 @@ func TestProviders(t *testing.T) {
124137
require.Equal(t, expectedBody, string(body))
125138
}
126139

127-
t.Run("JSON Response", func(t *testing.T) {
128-
runTest(t, mediaTypeJSON, false, `{"Providers":[{"Addrs":[],"ID":"12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vn","Protocols":["transport-bitswap"],"Schema":"peer"},{"Addrs":[],"ID":"12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vz","Protocols":["transport-bitswap"],"Schema":"peer"}]}`)
140+
t.Run("GET /routing/v1/peers/{cid} (JSON Response)", func(t *testing.T) {
141+
runGetTest(t, mediaTypeJSON, false, `{"Providers":[{"Addrs":[],"ID":"`+pid1Str+`","Protocols":["transport-bitswap"],"Schema":"peer"},{"Addrs":[],"ID":"`+pid2Str+`","Protocols":["transport-bitswap"],"Schema":"peer"}]}`)
129142
})
130143

131-
t.Run("NDJSON Response", func(t *testing.T) {
132-
runTest(t, mediaTypeNDJSON, true, `{"Addrs":[],"ID":"12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vn","Protocols":["transport-bitswap"],"Schema":"peer"}`+"\n"+`{"Addrs":[],"ID":"12D3KooWM8sovaEGU1bmiWGWAzvs47DEcXKZZTuJnpQyVTkRs2Vz","Protocols":["transport-bitswap"],"Schema":"peer"}`+"\n")
144+
t.Run("GET /routing/v1/peers/{cid} (NDJSON Response)", func(t *testing.T) {
145+
runGetTest(t, mediaTypeNDJSON, true, `{"Addrs":[],"ID":"`+pid1Str+`","Protocols":["transport-bitswap"],"Schema":"peer"}`+"\n"+`{"Addrs":[],"ID":"`+pid2Str+`","Protocols":["transport-bitswap"],"Schema":"peer"}`+"\n")
146+
})
147+
148+
runPutTest := func(t *testing.T, contentType string, expectedBody string) {
149+
t.Parallel()
150+
151+
rec1 := &types.AnnouncementRecord{
152+
Schema: types.SchemaAnnouncement,
153+
Payload: types.AnnouncementPayload{
154+
CID: cid1,
155+
Timestamp: time.Now().UTC(),
156+
TTL: time.Hour,
157+
ID: &pid1,
158+
Protocols: []string{"transport-🌈"},
159+
},
160+
}
161+
err := rec1.Sign(pid1, sk1)
162+
require.NoError(t, err)
163+
164+
rec2 := &types.AnnouncementRecord{
165+
Schema: types.SchemaAnnouncement,
166+
Payload: types.AnnouncementPayload{
167+
CID: cid1,
168+
Timestamp: time.Now().UTC(),
169+
TTL: time.Hour,
170+
ID: &pid2,
171+
Protocols: []string{"transport-🌈"},
172+
},
173+
}
174+
err = rec2.Sign(pid2, sk2)
175+
require.NoError(t, err)
176+
177+
req := tjson.AnnounceProvidersRequest{Providers: []types.Record{rec1, rec2}}
178+
body, err := json.Marshal(req)
179+
require.NoError(t, err)
180+
181+
router := &mockContentRouter{}
182+
server := httptest.NewServer(Handler(router))
183+
t.Cleanup(server.Close)
184+
185+
serverAddr := "http://" + server.Listener.Addr().String()
186+
187+
router.On("Provide", mock.Anything, &ProvideRequest{
188+
CID: cid1,
189+
Timestamp: rec1.Payload.Timestamp,
190+
TTL: rec1.Payload.TTL,
191+
ID: pid1,
192+
Addrs: []multiaddr.Multiaddr{},
193+
Protocols: rec1.Payload.Protocols,
194+
}).Return(time.Hour, nil)
195+
196+
router.On("Provide", mock.Anything, &ProvideRequest{
197+
CID: cid1,
198+
Timestamp: rec2.Payload.Timestamp,
199+
TTL: rec2.Payload.TTL,
200+
ID: pid2,
201+
Addrs: []multiaddr.Multiaddr{},
202+
Protocols: rec2.Payload.Protocols,
203+
}).Return(time.Minute, nil)
204+
205+
urlStr := serverAddr + "/routing/v1/providers"
206+
207+
httpReq, err := http.NewRequest(http.MethodPut, urlStr, bytes.NewReader(body))
208+
require.NoError(t, err)
209+
httpReq.Header.Set("Accept", contentType)
210+
211+
resp, err := http.DefaultClient.Do(httpReq)
212+
require.NoError(t, err)
213+
require.Equal(t, 200, resp.StatusCode)
214+
header := resp.Header.Get("Content-Type")
215+
require.Equal(t, contentType, header)
216+
217+
body, err = io.ReadAll(resp.Body)
218+
require.NoError(t, err)
219+
220+
require.Equal(t, expectedBody, string(body))
221+
}
222+
223+
t.Run("PUT /routing/v1/providers (JSON Response)", func(t *testing.T) {
224+
runPutTest(t, mediaTypeJSON, `{"ProvideResults":[{"Schema":"announcement","Payload":{"Addrs":[],"CID":"`+cid1Str+`","ID":"`+pid1Str+`","Protocols":[],"TTL":3600000}},{"Schema":"announcement","Payload":{"Addrs":[],"CID":"`+cid1Str+`","ID":"`+pid2Str+`","Protocols":[],"TTL":60000}}]}`)
225+
})
226+
227+
t.Run("PUT /routing/v1/providers (NDJSON Response)", func(t *testing.T) {
228+
runPutTest(t, mediaTypeNDJSON, `{"Schema":"announcement","Payload":{"Addrs":[],"CID":"`+cid1Str+`","ID":"`+pid1Str+`","Protocols":[],"TTL":3600000}}`+"\n"+`{"Schema":"announcement","Payload":{"Addrs":[],"CID":"`+cid1Str+`","ID":"`+pid2Str+`","Protocols":[],"TTL":60000}}`+"\n")
133229
})
134230
}
135231

136232
func TestPeers(t *testing.T) {
137-
makeRequest := func(t *testing.T, router *mockContentRouter, contentType, arg string) *http.Response {
233+
makeGetRequest := func(t *testing.T, router *mockContentRouter, contentType, arg string) *http.Response {
138234
server := httptest.NewServer(Handler(router))
139235
t.Cleanup(server.Close)
140236
req, err := http.NewRequest(http.MethodGet, "http://"+server.Listener.Addr().String()+"/routing/v1/peers/"+arg, nil)
@@ -149,7 +245,7 @@ func TestPeers(t *testing.T) {
149245
t.Parallel()
150246

151247
router := &mockContentRouter{}
152-
resp := makeRequest(t, router, mediaTypeJSON, "bafkqaaa")
248+
resp := makeGetRequest(t, router, mediaTypeJSON, "bafkqaaa")
153249
require.Equal(t, 400, resp.StatusCode)
154250
})
155251

@@ -158,7 +254,7 @@ func TestPeers(t *testing.T) {
158254

159255
_, pid := makePeerID(t)
160256
router := &mockContentRouter{}
161-
resp := makeRequest(t, router, mediaTypeJSON, b58.Encode([]byte(pid)))
257+
resp := makeGetRequest(t, router, mediaTypeJSON, b58.Encode([]byte(pid)))
162258
require.Equal(t, 400, resp.StatusCode)
163259
})
164260

@@ -184,7 +280,7 @@ func TestPeers(t *testing.T) {
184280
router := &mockContentRouter{}
185281
router.On("FindPeers", mock.Anything, pid, 20).Return(results, nil)
186282

187-
resp := makeRequest(t, router, mediaTypeJSON, peer.ToCid(pid).String())
283+
resp := makeGetRequest(t, router, mediaTypeJSON, peer.ToCid(pid).String())
188284
require.Equal(t, 200, resp.StatusCode)
189285

190286
header := resp.Header.Get("Content-Type")
@@ -219,7 +315,7 @@ func TestPeers(t *testing.T) {
219315
router := &mockContentRouter{}
220316
router.On("FindPeers", mock.Anything, pid, 0).Return(results, nil)
221317

222-
resp := makeRequest(t, router, mediaTypeNDJSON, peer.ToCid(pid).String())
318+
resp := makeGetRequest(t, router, mediaTypeNDJSON, peer.ToCid(pid).String())
223319
require.Equal(t, 200, resp.StatusCode)
224320

225321
header := resp.Header.Get("Content-Type")
@@ -231,6 +327,88 @@ func TestPeers(t *testing.T) {
231327
expectedBody := `{"Addrs":[],"ID":"` + pid.String() + `","Protocols":["transport-bitswap","transport-foo"],"Schema":"peer"}` + "\n" + `{"Addrs":[],"ID":"` + pid.String() + `","Protocols":["transport-foo"],"Schema":"peer"}` + "\n"
232328
require.Equal(t, expectedBody, string(body))
233329
})
330+
331+
sk1, pid1 := makePeerID(t)
332+
sk2, pid2 := makePeerID(t)
333+
334+
runPutTest := func(t *testing.T, contentType string, expectedBody string) {
335+
t.Parallel()
336+
337+
rec1 := &types.AnnouncementRecord{
338+
Schema: types.SchemaAnnouncement,
339+
Payload: types.AnnouncementPayload{
340+
Timestamp: time.Now().UTC(),
341+
TTL: time.Hour,
342+
ID: &pid1,
343+
Protocols: []string{"transport-🌈"},
344+
},
345+
}
346+
err := rec1.Sign(pid1, sk1)
347+
require.NoError(t, err)
348+
349+
rec2 := &types.AnnouncementRecord{
350+
Schema: types.SchemaAnnouncement,
351+
Payload: types.AnnouncementPayload{
352+
Timestamp: time.Now().UTC(),
353+
TTL: time.Hour,
354+
ID: &pid2,
355+
Protocols: []string{"transport-🌈"},
356+
},
357+
}
358+
err = rec2.Sign(pid2, sk2)
359+
require.NoError(t, err)
360+
361+
req := tjson.AnnounceProvidersRequest{Providers: []types.Record{rec1, rec2}}
362+
body, err := json.Marshal(req)
363+
require.NoError(t, err)
364+
365+
router := &mockContentRouter{}
366+
server := httptest.NewServer(Handler(router))
367+
t.Cleanup(server.Close)
368+
369+
serverAddr := "http://" + server.Listener.Addr().String()
370+
371+
router.On("ProvidePeer", mock.Anything, &ProvidePeerRequest{
372+
Timestamp: rec1.Payload.Timestamp,
373+
TTL: rec1.Payload.TTL,
374+
ID: pid1,
375+
Addrs: []multiaddr.Multiaddr{},
376+
Protocols: rec1.Payload.Protocols,
377+
}).Return(time.Hour, nil)
378+
379+
router.On("ProvidePeer", mock.Anything, &ProvidePeerRequest{
380+
Timestamp: rec2.Payload.Timestamp,
381+
TTL: rec2.Payload.TTL,
382+
ID: pid2,
383+
Addrs: []multiaddr.Multiaddr{},
384+
Protocols: rec2.Payload.Protocols,
385+
}).Return(time.Minute, nil)
386+
387+
urlStr := serverAddr + "/routing/v1/peers"
388+
389+
httpReq, err := http.NewRequest(http.MethodPut, urlStr, bytes.NewReader(body))
390+
require.NoError(t, err)
391+
httpReq.Header.Set("Accept", contentType)
392+
393+
resp, err := http.DefaultClient.Do(httpReq)
394+
require.NoError(t, err)
395+
require.Equal(t, 200, resp.StatusCode)
396+
header := resp.Header.Get("Content-Type")
397+
require.Equal(t, contentType, header)
398+
399+
body, err = io.ReadAll(resp.Body)
400+
require.NoError(t, err)
401+
402+
require.Equal(t, expectedBody, string(body))
403+
}
404+
405+
t.Run("PUT /routing/v1/peers (JSON Response)", func(t *testing.T) {
406+
runPutTest(t, mediaTypeJSON, `{"ProvideResults":[{"Schema":"announcement","Payload":{"Addrs":[],"ID":"`+pid1.String()+`","Protocols":[],"TTL":3600000}},{"Schema":"announcement","Payload":{"Addrs":[],"ID":"`+pid2.String()+`","Protocols":[],"TTL":60000}}]}`)
407+
})
408+
409+
t.Run("PUT /routing/v1/peers (NDJSON Response)", func(t *testing.T) {
410+
runPutTest(t, mediaTypeNDJSON, `{"Schema":"announcement","Payload":{"Addrs":[],"ID":"`+pid1.String()+`","Protocols":[],"TTL":3600000}}`+"\n"+`{"Schema":"announcement","Payload":{"Addrs":[],"ID":"`+pid2.String()+`","Protocols":[],"TTL":60000}}`+"\n")
411+
})
234412
}
235413

236414
func makeName(t *testing.T) (crypto.PrivKey, ipns.Name) {

0 commit comments

Comments
 (0)