Skip to content

Commit 169827e

Browse files
committed
✅ [channel/test,backend/eth/channel] Generic subscription test
Signed-off-by: Matthias Geihs <[email protected]>
1 parent c4f3067 commit 169827e

File tree

2 files changed

+188
-0
lines changed

2 files changed

+188
-0
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Copyright 2021 - See NOTICE file for copyright holders.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package channel_test
16+
17+
import (
18+
"context"
19+
"testing"
20+
21+
"github.com/stretchr/testify/require"
22+
"perun.network/go-perun/backend/ethereum/channel/test"
23+
"perun.network/go-perun/channel"
24+
channeltest "perun.network/go-perun/channel/test"
25+
pkgtest "perun.network/go-perun/pkg/test"
26+
)
27+
28+
func TestSubscription(t *testing.T) {
29+
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
30+
defer cancel()
31+
32+
rng := pkgtest.Prng(t)
33+
numParts := 2 + rng.Intn(maxNumParts-2)
34+
setup := test.NewSetup(t, rng, numParts, blockInterval)
35+
adjSetup := newAdjudicatorSetup(setup)
36+
adj := adjSetup.Adjudicator()
37+
38+
req, subChannels := adjSetup.newAdjudicatorReq(ctx, rng, channeltest.WithoutApp()), []channel.SignedState{}
39+
sub, err := adj.Subscribe(ctx, req.Params.ID())
40+
require.NoError(t, err, "subscribing")
41+
42+
subSetup := newSubscriptionSetup(sub, adj, req, subChannels)
43+
channeltest.TestSubscription(ctx, t, subSetup)
44+
}
45+
46+
type subscriptionSetup struct {
47+
adj channel.Adjudicator
48+
sub *testSubscription
49+
req *channel.AdjudicatorReq
50+
subChannels []channel.SignedState
51+
}
52+
53+
func newSubscriptionSetup(
54+
sub channel.AdjudicatorSubscription,
55+
adj channel.Adjudicator,
56+
req *channel.AdjudicatorReq,
57+
subChannels []channel.SignedState,
58+
) *subscriptionSetup {
59+
return &subscriptionSetup{
60+
sub: &testSubscription{
61+
emitProgressed: false,
62+
req: req,
63+
AdjudicatorSubscription: sub,
64+
},
65+
adj: adj,
66+
req: req,
67+
subChannels: subChannels,
68+
}
69+
}
70+
71+
type testSubscription struct {
72+
channel.AdjudicatorSubscription
73+
emitProgressed bool
74+
req *channel.AdjudicatorReq
75+
}
76+
77+
// Next emulates app channel functionality because app channels are not supported yet.
78+
func (s *testSubscription) Next() channel.AdjudicatorEvent {
79+
if s.emitProgressed {
80+
s.emitProgressed = false
81+
return channel.NewProgressedEvent(s.req.Tx.ID, &channel.ElapsedTimeout{}, s.req.Tx.State, s.req.Idx)
82+
}
83+
return s.AdjudicatorSubscription.Next()
84+
}
85+
86+
func (s *subscriptionSetup) Subscription() channel.AdjudicatorSubscription {
87+
return s.sub
88+
}
89+
90+
// EmitRegistered operates the adjudicator so that a registered event should be emitted.
91+
func (s *subscriptionSetup) EmitRegistered(ctx context.Context) (channel.Params, channel.State) {
92+
err := s.adj.Register(ctx, *s.req, s.subChannels)
93+
if err != nil {
94+
panic(err)
95+
}
96+
return *s.req.Params, *s.req.Tx.State
97+
}
98+
99+
// EmitProgressed emulates app channel functionality because app channels are not supported yet.
100+
func (s *subscriptionSetup) EmitProgressed(ctx context.Context) (channel.Params, channel.State) {
101+
s.sub.emitProgressed = true
102+
return *s.req.Params, *s.req.Tx.State
103+
}
104+
105+
// EmitRegistered operates the adjudicator so that a concluded event should be emitted.
106+
func (s *subscriptionSetup) EmitConcluded(ctx context.Context) channel.Params {
107+
err := s.adj.Withdraw(ctx, *s.req, channeltest.MakeStateMapFromSignedStates(s.subChannels...))
108+
if err != nil {
109+
panic(err)
110+
}
111+
return *s.req.Params
112+
}

channel/test/subscription.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// Copyright 2021 - See NOTICE file for copyright holders.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package test
16+
17+
import (
18+
"context"
19+
"testing"
20+
21+
"github.com/stretchr/testify/assert"
22+
"perun.network/go-perun/channel"
23+
)
24+
25+
// SubscriptionTestSetup represents a setup for testing a subscription implementation.
26+
//
27+
// Subscription should return an instance of the subscription implementation.
28+
// EmitRegistered should make the subscription emit a registered event.
29+
// EmitProgressed should make the subscription emit a progressed event.
30+
// EmitConcluded should make the subscription emit a concluded event.
31+
type SubscriptionTestSetup interface {
32+
Subscription() channel.AdjudicatorSubscription
33+
EmitRegistered(context.Context) (channel.Params, channel.State)
34+
EmitProgressed(context.Context) (channel.Params, channel.State)
35+
EmitConcluded(context.Context) channel.Params
36+
}
37+
38+
func TestSubscription(ctx context.Context, t *testing.T, s SubscriptionTestSetup) {
39+
sub := s.Subscription()
40+
41+
{
42+
params, state := s.EmitRegistered(ctx)
43+
e, ok := sub.Next().(*channel.RegisteredEvent)
44+
assert.True(t, ok, "registered")
45+
assert.True(t, e.ID() == params.ID(), "equal ID")
46+
assert.True(t, e.State.Equal(&state) == nil, "equal state")
47+
err := e.Timeout().Wait(ctx)
48+
assert.NoError(t, err, "registered: waiting")
49+
}
50+
51+
{
52+
params, state := s.EmitProgressed(ctx)
53+
e, ok := sub.Next().(*channel.ProgressedEvent)
54+
assert.True(t, ok, "progressed")
55+
assert.True(t, e.ID() == params.ID(), "equal ID")
56+
assert.True(t, e.State.Equal(&state) == nil, "equal state")
57+
err := e.Timeout().Wait(ctx)
58+
assert.NoError(t, err, "progressed: waiting")
59+
}
60+
61+
{
62+
params := s.EmitConcluded(ctx)
63+
e, ok := sub.Next().(*channel.ConcludedEvent)
64+
assert.True(t, ok, "concluded")
65+
assert.True(t, e.ID() == params.ID(), "equal ID")
66+
err := e.Timeout().Wait(ctx)
67+
assert.NoError(t, err, "concluded: waiting")
68+
}
69+
70+
{
71+
err := sub.Close()
72+
assert.NoError(t, err, "close")
73+
err = sub.Err()
74+
assert.NoError(t, err, "err")
75+
}
76+
}

0 commit comments

Comments
 (0)