@cryptotaxi247 / kubo / commits / fd830b3c1

test: fix flaky content routing over HTTP test (#9772)

Gus Eggert committed Apr 5, 2023 at 07:10 UTC fd830b3c1a1aeda55504f28fe6a268e92cc30225
2 files changed +104 -61
test/cli/content_routing_http_test.go new
+104
@@ -0,0 +1,104 @@
1 +package cli
2 +
3 +import (
4 + "context"
5 + "net/http"
6 + "net/http/httptest"
7 + "os/exec"
8 + "sync"
9 + "testing"
10 + "time"
11 +
12 + "github.com/ipfs/boxo/routing/http/server"
13 + "github.com/ipfs/boxo/routing/http/types"
14 + "github.com/ipfs/go-cid"
15 + "github.com/ipfs/kubo/test/cli/harness"
16 + "github.com/ipfs/kubo/test/cli/testutils"
17 + "github.com/stretchr/testify/assert"
18 +)
19 +
20 +type fakeHTTPContentRouter struct {
21 + m sync.Mutex
22 + findProvidersCalls int
23 + provideCalls int
24 +}
25 +
26 +func (r *fakeHTTPContentRouter) FindProviders(ctx context.Context, key cid.Cid) ([]types.ProviderResponse, error) {
27 + r.m.Lock()
28 + defer r.m.Unlock()
29 + r.findProvidersCalls++
30 + return []types.ProviderResponse{}, nil
31 +}
32 +
33 +func (r *fakeHTTPContentRouter) ProvideBitswap(ctx context.Context, req *server.BitswapWriteProvideRequest) (time.Duration, error) {
34 + r.m.Lock()
35 + defer r.m.Unlock()
36 + r.provideCalls++
37 + return 0, nil
38 +}
39 +func (r *fakeHTTPContentRouter) Provide(ctx context.Context, req *server.WriteProvideRequest) (types.ProviderResponse, error) {
40 + r.m.Lock()
41 + defer r.m.Unlock()
42 + r.provideCalls++
43 + return nil, nil
44 +}
45 +
46 +func (r *fakeHTTPContentRouter) numFindProvidersCalls() int {
47 + r.m.Lock()
48 + defer r.m.Unlock()
49 + return r.findProvidersCalls
50 +}
51 +
52 +// userAgentRecorder records the user agent of every HTTP request
53 +type userAgentRecorder struct {
54 + delegate http.Handler
55 + userAgents []string
56 +}
57 +
58 +func (r *userAgentRecorder) ServeHTTP(w http.ResponseWriter, req *http.Request) {
59 + r.userAgents = append(r.userAgents, req.UserAgent())
60 + r.delegate.ServeHTTP(w, req)
61 +}
62 +
63 +func TestContentRoutingHTTP(t *testing.T) {
64 + cr := &fakeHTTPContentRouter{}
65 +
66 + // run the content routing HTTP server
67 + userAgentRecorder := &userAgentRecorder{delegate: server.Handler(cr)}
68 + server := httptest.NewServer(userAgentRecorder)
69 + t.Cleanup(func() { server.Close() })
70 +
71 + // setup the node
72 + node := harness.NewT(t).NewNode().Init()
73 + node.Runner.Env["IPFS_HTTP_ROUTERS"] = server.URL
74 + node.StartDaemon()
75 +
76 + // compute a random CID
77 + randStr := string(testutils.RandomBytes(100))
78 + res := node.PipeStrToIPFS(randStr, "add", "-qn")
79 + wantCIDStr := res.Stdout.Trimmed()
80 +
81 + t.Run("fetching an uncached block results in an HTTP lookup", func(t *testing.T) {
82 + statRes := node.Runner.Run(harness.RunRequest{
83 + Path: node.IPFSBin,
84 + Args: []string{"block", "stat", wantCIDStr},
85 + RunFunc: (*exec.Cmd).Start,
86 + })
87 + defer func() {
88 + if err := statRes.Cmd.Process.Kill(); err != nil {
89 + t.Logf("error killing 'block stat' cmd: %s", err)
90 + }
91 + }()
92 +
93 + // verify the content router was called
94 + assert.Eventually(t, func() bool {
95 + return cr.numFindProvidersCalls() > 0
96 + }, time.Minute, 10*time.Millisecond)
97 +
98 + assert.NotEmpty(t, userAgentRecorder.userAgents)
99 + version := node.IPFS("id", "-f", "<aver>").Stdout.Trimmed()
100 + for _, userAgent := range userAgentRecorder.userAgents {
101 + assert.Equal(t, version, userAgent)
102 + }
103 + })
104 +}
test/sharness/t0172-content-routing-over-http.sh deleted
-61
@@ -1,61 +0,0 @@
1 -#!/usr/bin/env bash
2 -
3 -test_description="Test content routing over HTTP"
4 -
5 -. lib/test-lib.sh
6 -
7 -
8 -if ! test_have_prereq SOCAT; then
9 - skip_all="skipping '$test_description': socat is not available"
10 - test_done
11 -fi
12 -
13 -test_init_ipfs
14 -
15 -# Run listener on a free port to log HTTP requests sent by Kubo in Routing.Type=auto mode
16 -export ROUTER_PORT=$(comm -23 <(seq 49152 65535 | sort) <(ss -Htan | awk '{print $4}' | cut -d':' -f2) | head -n 1)
17 -export IPFS_HTTP_ROUTERS="http://127.0.0.1:$ROUTER_PORT"
18 -
19 -test_launch_ipfs_daemon
20 -
21 -test_expect_success "start HTTP router proxy" '
22 - touch http_requests
23 - socat -u TCP-LISTEN:$ROUTER_PORT,reuseaddr,fork,bind=127.0.0.1,retry=10 CREATE:http_requests &
24 - NCPID=$!
25 -'
26 -
27 -## HTTP GETs
28 -
29 -test_expect_success 'create unique CID without adding it to the local datastore' '
30 - WANT_CID=$(date +"%FT%T.%N%z" | ipfs add -qn)
31 -'
32 -
33 -test_expect_success 'expect HTTP lookup when CID is not in the local datastore' '
34 - ipfs block stat "$WANT_CID" &
35 - test_wait_output_n_lines http_requests 4 &&
36 - test_should_contain "GET /routing/v1/providers/$WANT_CID" http_requests
37 -'
38 -
39 -test_expect_success 'expect HTTP request User-Agent to match Kubo version' '
40 - test_should_contain "User-Agent: $(ipfs id -f "<aver>")" http_requests
41 -'
42 -
43 -## HTTP PUTs
44 -
45 -test_expect_success 'add new CID to the local datastore' '
46 - ADD_CID=$(date +"%FT%T.%N%z" | ipfs add -q)
47 -'
48 -
49 -# cid.contact supports GET-only: https://github.com/ipfs/kubo/issues/9504
50 -# which means no announcements over HTTP should be made.
51 -test_expect_success 'expect no HTTP requests to be sent with locally added CID' '
52 - test_should_not_contain "$ADD_CID" http_requests
53 -'
54 -
55 -test_expect_success "stop nc" '
56 - kill "$NCPID" && wait "$NCPID" || true
57 - rm -f http_requests || true
58 -'
59 -
60 -test_kill_ipfs_daemon
61 -test_done