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

feat/simulated: support fvm sumulator in unit test/支持在单元测试中进行fvm系统调用层模拟 #76

Merged
merged 13 commits into from
Sep 22, 2022
1 change: 1 addition & 0 deletions examples/erc20/contract/erc20.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ func (t *Erc20Token) Transfer(transferReq *TransferReq) error {
if err != nil {
return err
}

receiverID, err := sdk.ResolveAddress(transferReq.ReceiverAddr)
if err != nil {
return err
Expand Down
219 changes: 219 additions & 0 deletions examples/erc20/contract/erc20_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
package contract

import (
"context"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/builtin/v9/migration"
"github.com/ipfs/go-cid"
"math/rand"
"reflect"
"testing"

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/big"
"github.com/ipfs-force-community/go-fvm-sdk/sdk"
"github.com/ipfs-force-community/go-fvm-sdk/sdk/adt"
"github.com/ipfs-force-community/go-fvm-sdk/sdk/sys/simulated"
"github.com/ipfs-force-community/go-fvm-sdk/sdk/types"
"github.com/stretchr/testify/assert"
)

func makeErc20Token() Erc20Token {
map_, _ := adt.MakeEmptyMap(adt.AdtStore(context.Background()), adt.BalanceTableBitwidth)
web3creator marked this conversation as resolved.
Show resolved Hide resolved
cidtest, err := map_.Root()
if err != nil {
panic(err)
}
TotalSupplytest := big.NewInt(0)
web3creator marked this conversation as resolved.
Show resolved Hide resolved

return Erc20Token{Name: "name", Symbol: "symbol", Decimals: 8, TotalSupply: &TotalSupplytest, Balances: cidtest, Allowed: cidtest}
}

func makeFakeSetBalance() *FakeSetBalance {
Balance := big.NewInt(0)
web3creator marked this conversation as resolved.
Show resolved Hide resolved
addr, _ := address.NewIDAddress(uint64(rand.Int()))
hunjixin marked this conversation as resolved.
Show resolved Hide resolved
FakeSetBalance := FakeSetBalance{Addr: addr, Balance: &Balance}
return &FakeSetBalance
}

func TestErc20TokenFakeSetBalance(t *testing.T) {
simulated.Begin()

type args struct {
req *FakeSetBalance
}
tests := []struct {
name string
fields Erc20Token
args args
wantErr bool
}{
{name: "case1", fields: makeErc20Token(), args: args{req: makeFakeSetBalance()}, wantErr: true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tr := &Erc20Token{
Name: tt.fields.Name,
Symbol: tt.fields.Symbol,
Decimals: tt.fields.Decimals,
TotalSupply: tt.fields.TotalSupply,
Balances: tt.fields.Balances,
Allowed: tt.fields.Allowed,
}
if err := tr.FakeSetBalance(tt.args.req); (err != nil) != tt.wantErr {
t.Errorf("Erc20Token.FakeSetBalance() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
simulated.End()
}

func TestErc20TokenGetName(t *testing.T) {
simulated.Begin()
tests := []struct {
name string
fields Erc20Token
want types.CborString
}{
{name: "pass", fields: makeErc20Token(), want: types.CborString("name")},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tr := &Erc20Token{
Name: tt.fields.Name,
Symbol: tt.fields.Symbol,
Decimals: tt.fields.Decimals,
TotalSupply: tt.fields.TotalSupply,
Balances: tt.fields.Balances,
Allowed: tt.fields.Allowed,
}
if got := tr.GetName(); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Erc20Token.GetName() = %v, want %v", got, tt.want)
}
})
}
simulated.End()
}

func TestErc20TokenSaveState(t *testing.T) {
simulated.Begin()

erc20 := makeErc20Token()
sdk.SaveState(&erc20)

newSt := new(Erc20Token)
sdk.LoadState(newSt)
assert.Equal(t, *newSt, erc20)
simulated.End()
}

func TestErc20TokenGetBalanceOf(t1 *testing.T) {

simulated.Begin()
erc20 := makeErc20Token()
balanceMap, _ := adt.AsMap(adt.AdtStore(context.Background()), erc20.Balances, adt.BalanceTableBitwidth)
addr, _ := address.NewIDAddress(uint64(rand.Int()))
simulated.SetAccount(8899, addr, migration.Actor{})
balance := big.NewInt(100)
if err := balanceMap.Put(types.ActorKey(8899), &balance); err != nil {
panic(err)
}
newRoot, _ := balanceMap.Root()
erc20.Balances = newRoot
sdk.SaveState(&erc20)

type args struct {
addr *address.Address
}

tests := []struct {
name string
fields Erc20Token
args args
want *big.Int
wantErr bool
}{
{name: "pass", fields: erc20, args: args{addr: &addr}, want: &balance, wantErr: false},
}
for _, tt := range tests {
t1.Run(tt.name, func(t1 *testing.T) {
t := &Erc20Token{
Name: tt.fields.Name,
Symbol: tt.fields.Symbol,
Decimals: tt.fields.Decimals,
TotalSupply: tt.fields.TotalSupply,
Balances: tt.fields.Balances,
Allowed: tt.fields.Allowed,
}
got, err := t.GetBalanceOf(tt.args.addr)
if (err != nil) != tt.wantErr {
t1.Errorf("GetBalanceOf() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t1.Errorf("GetBalanceOf() got = %v, want %v", got, tt.want)
}
})
}
simulated.End()
}

func TestErc20TokenTransfer(t *testing.T) {
simulated.Begin()

erc20 := makeErc20Token()
// set info of caller
callactorid := uint32(8899)
calladdr, _ := address.NewIDAddress(uint64(rand.Int()))
simulated.SetAccount(callactorid, calladdr, migration.Actor{Code: cid.Undef, Head: cid.Undef, CallSeqNum: 0, Balance: big.NewInt(99)})

// push balance of caller
balanceMap, _ := adt.AsMap(adt.AdtStore(context.Background()), erc20.Balances, adt.BalanceTableBitwidth)
balance := big.NewInt(100000)
if err := balanceMap.Put(types.ActorKey(callactorid), &balance); err != nil {
panic(err)
}

newRoot, _ := balanceMap.Root()
erc20.Balances = newRoot
sdk.SaveState(&erc20)

// set info of receiver
receiactorid := uint32(7788)
receiveaddr, _ := address.NewIDAddress(uint64(rand.Int()))
simulated.SetAccount(receiactorid, receiveaddr, migration.Actor{Code: cid.Undef, Head: cid.Undef, CallSeqNum: 0, Balance: big.NewInt(99)})

// set info of context
callcontext := types.InvocationContext{Caller: abi.ActorID(callactorid)}
simulated.SetCallContext(&callcontext)

toamount := big.NewInt(99)
type args struct {
transferReq *TransferReq
}
tests := []struct {
name string
fields Erc20Token
args args
wantErr bool
}{
{name: "pass", fields: makeErc20Token(), args: args{transferReq: &TransferReq{ReceiverAddr: receiveaddr, TransferAmount: &toamount}}, wantErr: false},
hunjixin marked this conversation as resolved.
Show resolved Hide resolved
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tr := &Erc20Token{
Name: tt.fields.Name,
Symbol: tt.fields.Symbol,
Decimals: tt.fields.Decimals,
TotalSupply: tt.fields.TotalSupply,
Balances: tt.fields.Balances,
Allowed: tt.fields.Allowed,
}

if err := tr.Transfer(tt.args.transferReq); (err != nil) != tt.wantErr {
t.Errorf("Erc20Token.Transfer() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
simulated.End()
}
6 changes: 3 additions & 3 deletions examples/erc20/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ replace (
erc20 => ./
github.com/davecgh/go-spew => github.com/ipfs-force-community/go-spew v1.1.2-0.20220524052205-0034150c051a
github.com/filecoin-project/go-address => github.com/ipfs-force-community/go-address v0.0.7-0.20220524010936-42617a156be1
github.com/filecoin-project/go-state-types => github.com/ipfs-force-community/go-state-types v0.1.8-0.20220523102255-d400d329d9c1
github.com/ipfs-force-community/go-fvm-sdk => ../..
github.com/ipfs/go-block-format => github.com/ipfs-force-community/go-block-format v0.0.4-0.20220425095807-073e9266335c
//remove anything about reflect
Expand All @@ -25,11 +24,12 @@ replace (

require (
github.com/filecoin-project/go-address v0.0.6
github.com/filecoin-project/go-state-types v0.1.3
github.com/filecoin-project/go-state-types v0.1.12-alpha
github.com/filecoin-project/specs-actors/v8 v8.0.1
github.com/filecoin-project/venus v1.2.4
github.com/ipfs-force-community/go-fvm-sdk v0.0.0-00010101000000-000000000000
github.com/ipfs/go-cid v0.1.0
github.com/ipfs/go-cid v0.2.0
github.com/stretchr/testify v1.7.0
github.com/whyrusleeping/cbor-gen v0.0.0-20220323183124-98fa8256a799
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f
)
Loading