@cryptotaxi247 / kubo / commits / e8ba4fc01

p2p: fix sharness tests after refactor

License: MIT Signed-off-by: Łukasz Magiera <magik6k@gmail.com>

Łukasz Magiera committed May 26, 2018 at 15:56 UTC e8ba4fc01af146201c790acfadaed898c072c899
5 files changed +189 -60
core/commands/p2p.go
+28 -6
@@ -88,7 +88,7 @@ Examples:
88 cmdkit.StringArg("target-address", true, false, "Target endpoint."),
89 },
90 Run: func(req cmds.Request, res cmds.Response) {
91 - n, err := getNode(req)
91 + n, err := p2pGetNode(req)
92 if err != nil {
93 res.SetError(err, cmdkit.ErrNormal)
94 return
@@ -164,7 +164,7 @@ var p2pLsCmd = &cmds.Command{
164 cmdkit.BoolOption("headers", "v", "Print table headers (Protocol, Listen, Target)."),
165 },
166 Run: func(req cmds.Request, res cmds.Response) {
167 - n, err := getNode(req)
167 + n, err := p2pGetNode(req)
168 if err != nil {
169 res.SetError(err, cmdkit.ErrNormal)
170 return
@@ -221,7 +221,7 @@ var p2pCloseCmd = &cmds.Command{
221 Run: func(req cmds.Request, res cmds.Response) {
222 res.SetOutput(nil)
223
224 - n, err := getNode(req)
224 + n, err := p2pGetNode(req)
225 if err != nil {
226 res.SetError(err, cmdkit.ErrNormal)
227 return
@@ -244,6 +244,10 @@ var p2pCloseCmd = &cmds.Command{
244
245 match := func(listener p2p.Listener) bool {
246 out := true
247 + if p || !strings.HasPrefix(proto, "/p2p/") {
248 + proto = "/p2p/" + proto
249 + }
250 +
251 if p {
252 out = out && (proto == listener.Protocol())
253 }
@@ -258,12 +262,30 @@ var p2pCloseCmd = &cmds.Command{
262 return out
263 }
264
265 + var closed int
266 for _, listener := range n.P2P.Listeners.Listeners {
267 if !match(listener) {
268 continue
269 }
270 listener.Close()
271 + closed++
272 }
273 + res.SetOutput(closed)
274 + },
275 + Type: int(0),
276 + Marshalers: cmds.MarshalerMap{
277 + cmds.Text: func(res cmds.Response) (io.Reader, error) {
278 + v, err := unwrapOutput(res.Output())
279 + if err != nil {
280 + return nil, err
281 + }
282 +
283 + closed := v.(int)
284 + buf := new(bytes.Buffer)
285 + fmt.Fprintf(buf, "Closed %d stream(s)\n", closed)
286 +
287 + return buf, nil
288 + },
289 },
290 }
291
@@ -292,7 +314,7 @@ var p2pStreamLsCmd = &cmds.Command{
314 cmdkit.BoolOption("headers", "v", "Print table headers (HagndlerID, Protocol, Local, Remote)."),
315 },
316 Run: func(req cmds.Request, res cmds.Response) {
295 - n, err := getNode(req)
317 + n, err := p2pGetNode(req)
318 if err != nil {
319 res.SetError(err, cmdkit.ErrNormal)
320 return
@@ -352,7 +374,7 @@ var p2pStreamCloseCmd = &cmds.Command{
374 Run: func(req cmds.Request, res cmds.Response) {
375 res.SetOutput(nil)
376
355 - n, err := getNode(req)
377 + n, err := p2pGetNode(req)
378 if err != nil {
379 res.SetError(err, cmdkit.ErrNormal)
380 return
@@ -386,7 +408,7 @@ var p2pStreamCloseCmd = &cmds.Command{
408 },
409 }
410
389 -func getNode(req cmds.Request) (*core.IpfsNode, error) {
411 +func p2pGetNode(req cmds.Request) (*core.IpfsNode, error) {
412 n, err := req.InvocContext().GetNode()
413 if err != nil {
414 return nil, err
p2p/listener.go
+16 -1
@@ -2,6 +2,8 @@ package p2p
2
3 import (
4 "sync"
5 +
6 + "github.com/pkg/errors"
7 )
8
9 type Listener interface {
@@ -25,9 +27,22 @@ type ListenerRegistry struct {
27 lk *sync.Mutex
28 }
29
30 +func (r *ListenerRegistry) Lock(l Listener) error {
31 + r.lk.Lock()
32 +
33 + if _, ok := r.Listeners[getListenerKey(l)]; ok {
34 + r.lk.Unlock()
35 + return errors.New("listener already registered")
36 + }
37 + return nil
38 +}
39 +
40 +func (r *ListenerRegistry) Unlock() {
41 + r.lk.Unlock()
42 +}
43 +
44 // Register registers listenerInfo in this registry
45 func (r *ListenerRegistry) Register(l Listener) {
30 - r.lk.Lock()
46 defer r.lk.Unlock()
47
48 r.Listeners[getListenerKey(l)] = l
p2p/local.go
+14 -7
@@ -20,6 +20,7 @@ type localListener struct {
20 id peer.ID
21
22 proto string
23 + laddr ma.Multiaddr
24 peer peer.ID
25
26 listener manet.Listener
@@ -27,11 +28,6 @@ type localListener struct {
28
29 // ForwardLocal creates new P2P stream to a remote listener
30 func (p2p *P2P) ForwardLocal(ctx context.Context, peer peer.ID, proto string, bindAddr ma.Multiaddr) (Listener, error) {
30 - maListener, err := manet.Listen(bindAddr)
31 - if err != nil {
32 - return nil, err
33 - }
34 -
31 listener := &localListener{
32 ctx: ctx,
33
@@ -39,11 +35,22 @@ func (p2p *P2P) ForwardLocal(ctx context.Context, peer peer.ID, proto string, bi
35 id: p2p.identity,
36
37 proto: proto,
38 + laddr: bindAddr,
39 peer: peer,
40 + }
41
44 - listener: maListener,
42 + if err := p2p.Listeners.Lock(listener); err != nil {
43 + return nil, err
44 }
45
46 + maListener, err := manet.Listen(bindAddr)
47 + if err != nil {
48 + p2p.Listeners.Unlock()
49 + return nil, err
50 + }
51 +
52 + listener.listener = maListener
53 +
54 p2p.Listeners.Register(listener)
55 go listener.acceptConns()
56
@@ -109,7 +116,7 @@ func (l *localListener) Protocol() string {
116 }
117
118 func (l *localListener) ListenAddress() string {
112 - return l.listener.Multiaddr().String()
119 + return l.laddr.String()
120 }
121
122 func (l *localListener) TargetAddress() string {
p2p/remote.go
+15 -4
@@ -22,14 +22,16 @@ type remoteListener struct {
22
23 // ForwardRemote creates new p2p listener
24 func (p2p *P2P) ForwardRemote(ctx context.Context, proto string, addr ma.Multiaddr) (Listener, error) {
25 - listenerInfo := &remoteListener{
25 + listener := &remoteListener{
26 p2p: p2p,
27
28 proto: proto,
29 addr: addr,
30 }
31
32 - p2p.Listeners.Register(listenerInfo)
32 + if err := p2p.Listeners.Lock(listener); err != nil {
33 + return nil, err
34 + }
35
36 p2p.peerHost.SetStreamHandler(protocol.ID(proto), func(remote net.Stream) {
37 local, err := manet.Dial(addr)
@@ -38,10 +40,17 @@ func (p2p *P2P) ForwardRemote(ctx context.Context, proto string, addr ma.Multiad
40 return
41 }
42
43 + //TODO: review: is there a better way to do this?
44 + peerMa, err := ma.NewMultiaddr("/ipfs/" + remote.Conn().RemotePeer().Pretty())
45 + if err != nil {
46 + remote.Reset()
47 + return
48 + }
49 +
50 stream := &Stream{
51 Protocol: proto,
52
44 - OriginAddr: remote.Conn().RemoteMultiaddr(),
53 + OriginAddr: peerMa,
54 TargetAddr: addr,
55
56 Local: local,
@@ -54,7 +63,9 @@ func (p2p *P2P) ForwardRemote(ctx context.Context, proto string, addr ma.Multiad
63 stream.startStreaming()
64 })
65
57 - return listenerInfo, nil
66 + p2p.Listeners.Register(listener)
67 +
68 + return listener, nil
69 }
70
71 func (l *remoteListener) Protocol() string {
test/sharness/t0180-p2p.sh
+116 -42
@@ -20,11 +20,13 @@ test_expect_success 'peer ids' '
20 PEERID_0=$(iptb get id 0) &&
21 PEERID_1=$(iptb get id 1)
22 '
23 -
24 -test_expect_success "test ports are closed" '
25 - (! (netstat -ln | grep "LISTEN" | grep ":10101 ")) &&
26 - (! (netstat -ln | grep "LISTEN" | grep ":10102 "))
27 -'
23 +check_test_ports() {
24 + test_expect_success "test ports are closed" '
25 + (! (netstat -lnp | grep "LISTEN" | grep ":10101 ")) &&
26 + (! (netstat -lnp | grep "LISTEN" | grep ":10102 "))
27 + '
28 +}
29 +check_test_ports
30
31 test_expect_success 'fail without config option being enabled' '
32 test_must_fail ipfsi 0 p2p stream ls
@@ -36,51 +38,105 @@ test_expect_success "enable filestore config setting" '
38 '
39
40 test_expect_success 'start p2p listener' '
39 - ipfsi 0 p2p listener open p2p-test /ip4/127.0.0.1/tcp/10101 2>&1 > listener-stdouterr.log
41 + ipfsi 0 p2p forward p2p-test /ipfs /ip4/127.0.0.1/tcp/10101 2>&1 > listener-stdouterr.log
42 '
43
42 -test_expect_success 'Test server to client communications' '
43 - ma-pipe-unidir --listen --pidFile=listener.pid send /ip4/127.0.0.1/tcp/10101 < test0.bin &
44 +# Server to client communications
45
45 - test_wait_for_file 30 100ms listener.pid &&
46 - kill -0 $(cat listener.pid) &&
46 +spawn_sending_server() {
47 + test_expect_success 'S->C Spawn sending server' '
48 + ma-pipe-unidir --listen --pidFile=listener.pid send /ip4/127.0.0.1/tcp/10101 < test0.bin &
49
48 - ipfsi 1 p2p stream dial $PEERID_0 p2p-test /ip4/127.0.0.1/tcp/10102 2>&1 > dialer-stdouterr.log &&
49 - ma-pipe-unidir recv /ip4/127.0.0.1/tcp/10102 > client.out &&
50 - test ! -f listener.pid
50 + test_wait_for_file 30 100ms listener.pid &&
51 + kill -0 $(cat listener.pid)
52 + '
53 +}
54 +
55 +test_server_to_client() {
56 + test_expect_success 'S->C Connect and receive data' '
57 + ma-pipe-unidir recv /ip4/127.0.0.1/tcp/10102 > client.out
58 + '
59 +
60 + test_expect_success 'S->C Ensure server finished' '
61 + test ! -f listener.pid
62 + '
63 +
64 + test_expect_success 'S->C Output looks good' '
65 + test_cmp client.out test0.bin
66 + '
67 +}
68 +
69 +spawn_sending_server
70 +
71 +test_expect_success 'S->C Setup client side' '
72 + ipfsi 1 p2p forward p2p-test /ip4/127.0.0.1/tcp/10102 /ipfs/${PEERID_0} 2>&1 > dialer-stdouterr.log
73 '
74
53 -test_expect_success 'Test client to server communications' '
75 +test_server_to_client
76 +
77 +test_expect_success 'S->C Connect with dead server' '
78 + ma-pipe-unidir recv /ip4/127.0.0.1/tcp/10102 > client.out
79 +'
80 +
81 +test_expect_success 'S->C Output is empty' '
82 + test_must_be_empty client.out
83 +'
84 +
85 +spawn_sending_server
86 +
87 +test_server_to_client
88 +
89 +test_expect_success 'S->C Close local listener' '
90 + ipfsi 1 p2p close -p p2p-test
91 +'
92 +
93 +check_test_ports
94 +
95 +# Client to server communications
96 +
97 +test_expect_success 'C->S Spawn receiving server' '
98 ma-pipe-unidir --listen --pidFile=listener.pid recv /ip4/127.0.0.1/tcp/10101 > server.out &
99
100 test_wait_for_file 30 100ms listener.pid &&
57 - kill -0 $(cat listener.pid) &&
101 + kill -0 $(cat listener.pid)
102 +'
103 +
104 +test_expect_success 'C->S Setup client side' '
105 + ipfsi 1 p2p forward p2p-test /ip4/127.0.0.1/tcp/10102 /ipfs/${PEERID_0} 2>&1 > dialer-stdouterr.log
106 +'
107 +
108 +test_expect_success 'C->S Connect and receive data' '
109 + ma-pipe-unidir send /ip4/127.0.0.1/tcp/10102 < test1.bin
110 +'
111
59 - ipfsi 1 p2p stream dial $PEERID_0 p2p-test /ip4/127.0.0.1/tcp/10102 2>&1 > dialer-stdouterr.log &&
60 - ma-pipe-unidir send /ip4/127.0.0.1/tcp/10102 < test1.bin &&
112 +test_expect_success 'C->S Ensure server finished' '
113 go-sleep 250ms &&
114 test ! -f listener.pid
115 '
116
65 -test_expect_success 'server to client output looks good' '
66 - test_cmp client.out test0.bin
117 +test_expect_success 'C->S Output looks good' '
118 + test_cmp server.out test1.bin
119 '
120
69 -test_expect_success 'client to server output looks good' '
70 - test_cmp server.out test1.bin
121 +test_expect_success 'C->S Close local listener' '
122 + ipfsi 1 p2p close -p p2p-test
123 '
124
73 -test_expect_success "'ipfs listener p2p ls' succeeds" '
74 - echo "/ip4/127.0.0.1/tcp/10101 /p2p/p2p-test" > expected &&
75 - ipfsi 0 p2p listener ls > actual
125 +check_test_ports
126 +
127 +# Listing streams
128 +
129 +test_expect_success "'ipfs p2p ls' succeeds" '
130 + echo "/p2p/p2p-test /ipfs /ip4/127.0.0.1/tcp/10101" > expected &&
131 + ipfsi 0 p2p ls > actual
132 '
133
78 -test_expect_success "'ipfs p2p listener ls' output looks good" '
134 +test_expect_success "'ipfs p2p ls' output looks good" '
135 test_cmp expected actual
136 '
137
138 test_expect_success "Cannot re-register app handler" '
83 - (! ipfsi 0 p2p listener open p2p-test /ip4/127.0.0.1/tcp/10101)
139 + test_must_fail ipfsi 0 p2p forward p2p-test /ipfs /ip4/127.0.0.1/tcp/10101
140 '
141
142 test_expect_success "'ipfs p2p stream ls' output is empty" '
@@ -91,7 +147,7 @@ test_expect_success "'ipfs p2p stream ls' output is empty" '
147 test_expect_success "Setup: Idle stream" '
148 ma-pipe-unidir --listen --pidFile=listener.pid recv /ip4/127.0.0.1/tcp/10101 &
149
94 - ipfsi 1 p2p stream dial $PEERID_0 p2p-test /ip4/127.0.0.1/tcp/10102 2>&1 > dialer-stdouterr.log &&
150 + ipfsi 1 p2p forward p2p-test /ip4/127.0.0.1/tcp/10102 /ipfs/$PEERID_0 2>&1 > dialer-stdouterr.log &&
151 ma-pipe-unidir --pidFile=client.pid recv /ip4/127.0.0.1/tcp/10102 &
152
153 test_wait_for_file 30 100ms listener.pid &&
@@ -100,7 +156,7 @@ test_expect_success "Setup: Idle stream" '
156 '
157
158 test_expect_success "'ipfs p2p stream ls' succeeds" '
103 - echo "2 /p2p/p2p-test /ip4/127.0.0.1/tcp/10101 $PEERID_1" > expected
159 + echo "3 /p2p/p2p-test /ipfs/$PEERID_1 /ip4/127.0.0.1/tcp/10101" > expected
160 ipfsi 0 p2p stream ls > actual
161 '
162
@@ -109,23 +165,31 @@ test_expect_success "'ipfs p2p stream ls' output looks good" '
165 '
166
167 test_expect_success "'ipfs p2p stream close' closes stream" '
112 - ipfsi 0 p2p stream close 2 &&
168 + ipfsi 0 p2p stream close 3 &&
169 ipfsi 0 p2p stream ls > actual &&
170 [ ! -f listener.pid ] && [ ! -f client.pid ] &&
171 test_must_be_empty actual
172 '
173
118 -test_expect_success "'ipfs p2p listener close' closes app handler" '
119 - ipfsi 0 p2p listener close p2p-test &&
120 - ipfsi 0 p2p listener ls > actual &&
174 +test_expect_success "'ipfs p2p close' closes remote handler" '
175 + ipfsi 0 p2p close -p p2p-test &&
176 + ipfsi 0 p2p ls > actual &&
177 test_must_be_empty actual
178 '
179
180 +test_expect_success "'ipfs p2p close' closes local handler" '
181 + ipfsi 1 p2p close -p p2p-test &&
182 + ipfsi 1 p2p ls > actual &&
183 + test_must_be_empty actual
184 +'
185 +
186 +check_test_ports
187 +
188 test_expect_success "Setup: Idle stream(2)" '
189 ma-pipe-unidir --listen --pidFile=listener.pid recv /ip4/127.0.0.1/tcp/10101 &
190
127 - ipfsi 0 p2p listener open p2p-test2 /ip4/127.0.0.1/tcp/10101 2>&1 > listener-stdouterr.log &&
128 - ipfsi 1 p2p stream dial $PEERID_0 p2p-test2 /ip4/127.0.0.1/tcp/10102 2>&1 > dialer-stdouterr.log &&
191 + ipfsi 0 p2p forward p2p-test2 /ipfs /ip4/127.0.0.1/tcp/10101 2>&1 > listener-stdouterr.log &&
192 + ipfsi 1 p2p forward p2p-test2 /ip4/127.0.0.1/tcp/10102 /ipfs/$PEERID_0 2>&1 > dialer-stdouterr.log &&
193 ma-pipe-unidir --pidFile=client.pid recv /ip4/127.0.0.1/tcp/10102 &
194
195 test_wait_for_file 30 100ms listener.pid &&
@@ -134,14 +198,20 @@ test_expect_success "Setup: Idle stream(2)" '
198 '
199
200 test_expect_success "'ipfs p2p stream ls' succeeds(2)" '
137 - echo "3 /p2p/p2p-test2 /ip4/127.0.0.1/tcp/10101 $PEERID_1" > expected
201 + echo "4 /p2p/p2p-test2 /ipfs/$PEERID_1 /ip4/127.0.0.1/tcp/10101" > expected
202 ipfsi 0 p2p stream ls > actual
203 test_cmp expected actual
204 '
205
142 -test_expect_success "'ipfs p2p listener close -a' closes app handlers" '
143 - ipfsi 0 p2p listener close -a &&
144 - ipfsi 0 p2p listener ls > actual &&
206 +test_expect_success "'ipfs p2p close -a' closes remote app handlers" '
207 + ipfsi 0 p2p close -a &&
208 + ipfsi 0 p2p ls > actual &&
209 + test_must_be_empty actual
210 +'
211 +
212 +test_expect_success "'ipfs p2p close -a' closes local app handlers" '
213 + ipfsi 1 p2p close -a &&
214 + ipfsi 1 p2p ls > actual &&
215 test_must_be_empty actual
216 '
217
@@ -152,13 +222,17 @@ test_expect_success "'ipfs p2p stream close -a' closes streams" '
222 test_must_be_empty actual
223 '
224
155 -test_expect_success "'ipfs p2p listener close' closes app numeric handlers" '
156 - ipfsi 0 p2p listener open 1234 /ip4/127.0.0.1/tcp/10101 &&
157 - ipfsi 0 p2p listener close 1234 &&
158 - ipfsi 0 p2p listener ls > actual &&
225 +check_test_ports
226 +
227 +test_expect_success "'ipfs p2p close' closes app numeric handlers" '
228 + ipfsi 0 p2p forward 1234 /ipfs /ip4/127.0.0.1/tcp/10101 &&
229 + ipfsi 0 p2p close -p 1234 &&
230 + ipfsi 0 p2p ls > actual &&
231 test_must_be_empty actual
232 '
233
234 +check_test_ports
235 +
236 test_expect_success 'stop iptb' '
237 iptb stop
238 '