master
go 168 lines 3.64 KB
Raw
1 package rpc
2
3 import (
4 "context"
5 "errors"
6 "net/http"
7 "net/http/httptest"
8 "strconv"
9 "strings"
10 "sync"
11 "testing"
12 "time"
13
14 "github.com/ipfs/boxo/path"
15 "github.com/ipfs/kubo/config"
16 iface "github.com/ipfs/kubo/core/coreiface"
17 "github.com/ipfs/kubo/core/coreiface/tests"
18 "github.com/ipfs/kubo/test/cli/harness"
19 ma "github.com/multiformats/go-multiaddr"
20 )
21
22 type NodeProvider struct{}
23
24 func (np NodeProvider) MakeAPISwarm(t *testing.T, ctx context.Context, fullIdentity, online bool, n int) ([]iface.CoreAPI, error) {
25 h := harness.NewT(t)
26
27 apis := make([]iface.CoreAPI, n)
28 nodes := h.NewNodes(n)
29
30 var wg, zero sync.WaitGroup
31 zeroNode := nodes[0]
32 wg.Add(len(apis))
33 zero.Add(1)
34
35 var errs []error
36 var errsLk sync.Mutex
37
38 for i, n := range nodes {
39 go func(i int, n *harness.Node) {
40 if err := func() error {
41 defer wg.Done()
42 var err error
43
44 n.Init("--empty-repo")
45
46 c := n.ReadConfig()
47 c.Experimental.FilestoreEnabled = true
48 // only provide things we pin. Allows to test
49 // provide operations.
50 c.Provide.Strategy = config.NewOptionalString("roots")
51 n.WriteConfig(c)
52 n.StartDaemon("--enable-pubsub-experiment", "--offline="+strconv.FormatBool(!online))
53
54 if online {
55 if i > 0 {
56 zero.Wait()
57 n.Connect(zeroNode)
58 } else {
59 zero.Done()
60 }
61 }
62
63 apiMaddr, err := n.TryAPIAddr()
64 if err != nil {
65 return err
66 }
67
68 api, err := NewApi(apiMaddr)
69 if err != nil {
70 return err
71 }
72 apis[i] = api
73
74 // empty node is pinned even with --empty-repo, we don't want that
75 emptyNode, err := path.NewPath("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn")
76 if err != nil {
77 return err
78 }
79
80 if err := api.Pin().Rm(ctx, emptyNode); err != nil {
81 return err
82 }
83 return nil
84 }(); err != nil {
85 errsLk.Lock()
86 errs = append(errs, err)
87 errsLk.Unlock()
88 }
89 }(i, n)
90 }
91
92 wg.Wait()
93
94 return apis, errors.Join(errs...)
95 }
96
97 func TestHttpApi(t *testing.T) {
98 t.Parallel()
99
100 tests.TestApi(NodeProvider{})(t)
101 }
102
103 func Test_NewURLApiWithClient_With_Headers(t *testing.T) {
104 t.Parallel()
105
106 var (
107 headerToTest = "Test-Header"
108 expectedHeaderValue = "thisisaheadertest"
109 )
110 ts := httptest.NewServer(
111 http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
112 val := r.Header.Get(headerToTest)
113 if val != expectedHeaderValue {
114 w.WriteHeader(400)
115 return
116 }
117 http.ServeContent(w, r, "", time.Now(), strings.NewReader("test"))
118 }),
119 )
120 defer ts.Close()
121 api, err := NewURLApiWithClient(ts.URL, &http.Client{
122 Transport: &http.Transport{
123 Proxy: http.ProxyFromEnvironment,
124 DisableKeepAlives: true,
125 },
126 })
127 if err != nil {
128 t.Fatal(err)
129 }
130 api.Headers.Set(headerToTest, expectedHeaderValue)
131 p, err := path.NewPath("/ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv")
132 if err != nil {
133 t.Fatal(err)
134 }
135 if err := api.Pin().Rm(context.Background(), p); err != nil {
136 t.Fatal(err)
137 }
138 }
139
140 func Test_NewURLApiWithClient_HTTP_Variant(t *testing.T) {
141 t.Parallel()
142
143 testcases := []struct {
144 address string
145 expected string
146 }{
147 {address: "/ip4/127.0.0.1/tcp/80", expected: "http://127.0.0.1:80"},
148 {address: "/ip4/127.0.0.1/tcp/443/tls", expected: "https://127.0.0.1:443"},
149 {address: "/ip4/127.0.0.1/tcp/443/https", expected: "https://127.0.0.1:443"},
150 {address: "/ip4/127.0.0.1/tcp/443/tls/http", expected: "https://127.0.0.1:443"},
151 }
152
153 for _, tc := range testcases {
154 address, err := ma.NewMultiaddr(tc.address)
155 if err != nil {
156 t.Fatal(err)
157 }
158
159 api, err := NewApiWithClient(address, &http.Client{})
160 if err != nil {
161 t.Fatal(err)
162 }
163
164 if api.url != tc.expected {
165 t.Errorf("Expected = %s; got %s", tc.expected, api.url)
166 }
167 }
168 }