Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend generic channel tests #223

Closed
62 changes: 62 additions & 0 deletions backend/ethereum/channel/funder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,68 @@ func TestFunder_Fund_multi(t *testing.T) {
t.Run("10-party funding", func(t *testing.T) { testFunderFunding(t, 10) })
}

func TestFunder(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
defer cancel()

rng := pkgtest.Prng(t)

numParts := 2 + rng.Intn(maxNumParts-2)
s := test.NewSetup(t, rng, numParts, blockInterval)

funders := make([]channel.Funder, numParts)
for i := range funders {
funders[i] = s.Funders[i]
}

_f := &funderSetup{
setup: s,
funders: funders,
}
channeltest.TestFunder(ctx, t, rng, _f)
}

// funderSetup represents a funderSetup test setup.
type funderSetup struct {
setup *test.Setup
funders []channel.Funder
}

const maxNumParts = 8

func (f *funderSetup) Funders() []channel.Funder {
return f.funders
}

func (f *funderSetup) NewFundingRequests(ctx context.Context, t *testing.T, rng *rand.Rand) []channel.FundingReq {
params, state := f.newRandomParamsAndState(rng)

funders := f.funders
numParts := len(funders)
requests := make([]channel.FundingReq, numParts)
ggwpez marked this conversation as resolved.
Show resolved Hide resolved
for i := range funders {
requests[i] = *channel.NewFundingReq(params, state, channel.Index(i), state.Balances)
}
return requests
}

func (f *funderSetup) newRandomParamsAndState(rng *rand.Rand, opts ...channeltest.RandomOpt) (*channel.Params, *channel.State) {
_opts := f.defaultOpts()
_opts = append(_opts, opts...)
return channeltest.NewRandomParamsAndState(rng, _opts...)
}

func (f *funderSetup) defaultOpts() []channeltest.RandomOpt {
return []channeltest.RandomOpt{
ggwpez marked this conversation as resolved.
Show resolved Hide resolved
channeltest.WithChallengeDuration(100),
channeltest.WithParts(f.setup.Parts...),
channeltest.WithAssets((*ethchannel.Asset)(&f.setup.Asset)),
channeltest.WithLedgerChannel(true),
channeltest.WithVirtualChannel(false),
channeltest.WithNumLocked(0),
}
}

func testFunderFunding(t *testing.T, n int) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), defaultTxTimeout*time.Duration(n))
Expand Down
55 changes: 55 additions & 0 deletions channel/test/funder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright 2021 - See NOTICE file for copyright holders.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package test

import (
"context"
"math/rand"
"testing"

"github.com/stretchr/testify/require"
"perun.network/go-perun/channel"
)

// Funder represents a funder setup used for testing.
//
// Funders should return a set of funders used for testing.
// NewFundingRequests should return a new set of funding requests for the given funders.
type Funder interface {
ggwpez marked this conversation as resolved.
Show resolved Hide resolved
Funders() []channel.Funder
NewFundingRequests(context.Context, *testing.T, *rand.Rand) []channel.FundingReq
}

// TestFunder runs a set of generic funder tests.
func TestFunder(ctx context.Context, t *testing.T, rng *rand.Rand, f Funder) {
ggwpez marked this conversation as resolved.
Show resolved Hide resolved
funders := f.Funders()
requests := f.NewFundingRequests(ctx, t, rng)

errs := make(chan error, len(funders))
ggwpez marked this conversation as resolved.
Show resolved Hide resolved
for i := range funders {
go func(funder channel.Funder, req channel.FundingReq) {
errs <- funder.Fund(ctx, req)
ggwpez marked this conversation as resolved.
Show resolved Hide resolved
}(funders[i], requests[i])
}

for range funders {
select {
case err := <-errs:
require.NoError(t, err, "funding should work")
case <-ctx.Done():
t.Error(ctx.Err())
}
}
}