api: Test return types
This commit is contained in:
parent
31ff5230bb
commit
e632643801
@ -230,7 +230,7 @@ type FullNode interface {
|
|||||||
WalletSignMessage(context.Context, address.Address, *types.Message) (*types.SignedMessage, error)
|
WalletSignMessage(context.Context, address.Address, *types.Message) (*types.SignedMessage, error)
|
||||||
// WalletVerify takes an address, a signature, and some bytes, and indicates whether the signature is valid.
|
// WalletVerify takes an address, a signature, and some bytes, and indicates whether the signature is valid.
|
||||||
// The address does not have to be in the wallet.
|
// The address does not have to be in the wallet.
|
||||||
WalletVerify(context.Context, address.Address, []byte, *crypto.Signature) bool
|
WalletVerify(context.Context, address.Address, []byte, *crypto.Signature) (bool, error)
|
||||||
// WalletDefaultAddress returns the address marked as default in the wallet.
|
// WalletDefaultAddress returns the address marked as default in the wallet.
|
||||||
WalletDefaultAddress(context.Context) (address.Address, error)
|
WalletDefaultAddress(context.Context) (address.Address, error)
|
||||||
// WalletSetDefault marks the given address as as the default one.
|
// WalletSetDefault marks the given address as as the default one.
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func goCmd() string {
|
func goCmd() string {
|
||||||
@ -32,3 +36,68 @@ func TestDoesntDependOnFFI(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReturnTypes(t *testing.T) {
|
||||||
|
errType := reflect.TypeOf(new(error)).Elem()
|
||||||
|
bareIface := reflect.TypeOf(new(interface{})).Elem()
|
||||||
|
jmarsh := reflect.TypeOf(new(json.Marshaler)).Elem()
|
||||||
|
|
||||||
|
tst := func(api interface{}) func(t *testing.T) {
|
||||||
|
return func(t *testing.T) {
|
||||||
|
ra := reflect.TypeOf(api).Elem()
|
||||||
|
for i := 0; i < ra.NumMethod(); i++ {
|
||||||
|
m := ra.Method(i)
|
||||||
|
switch m.Type.NumOut() {
|
||||||
|
case 1: // if 1 return value, it must be an error
|
||||||
|
require.Equal(t, errType, m.Type.Out(0), m.Name)
|
||||||
|
|
||||||
|
case 2: // if 2 return values, first cant be an interface/function, second must be an error
|
||||||
|
seen := map[reflect.Type]struct{}{}
|
||||||
|
todo := []reflect.Type{m.Type.Out(0)}
|
||||||
|
for len(todo) > 0 {
|
||||||
|
typ := todo[len(todo) - 1]
|
||||||
|
todo = todo[:len(todo)-1]
|
||||||
|
|
||||||
|
if _, ok := seen[typ]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
seen[typ] = struct{}{}
|
||||||
|
|
||||||
|
if typ.Kind() == reflect.Interface && typ != bareIface && !typ.Implements(jmarsh) {
|
||||||
|
t.Error("methods can't return interfaces", m.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch typ.Kind() {
|
||||||
|
case reflect.Ptr:
|
||||||
|
fallthrough
|
||||||
|
case reflect.Array:
|
||||||
|
fallthrough
|
||||||
|
case reflect.Slice:
|
||||||
|
fallthrough
|
||||||
|
case reflect.Chan:
|
||||||
|
todo = append(todo, typ.Elem())
|
||||||
|
case reflect.Map:
|
||||||
|
todo = append(todo, typ.Elem())
|
||||||
|
todo = append(todo, typ.Key())
|
||||||
|
case reflect.Struct:
|
||||||
|
for i := 0; i < typ.NumField(); i++ {
|
||||||
|
todo = append(todo, typ.Field(i).Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
require.NotEqual(t, reflect.Func.String(), m.Type.Out(0).Kind().String(), m.Name)
|
||||||
|
require.Equal(t, errType, m.Type.Out(1), m.Name)
|
||||||
|
|
||||||
|
default:
|
||||||
|
t.Error("methods can only have 1 or 2 return values", m.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("common", tst(new(Common)))
|
||||||
|
t.Run("full", tst(new(FullNode)))
|
||||||
|
t.Run("miner", tst(new(StorageMiner)))
|
||||||
|
t.Run("worker", tst(new(WorkerAPI)))
|
||||||
|
}
|
||||||
|
@ -134,7 +134,7 @@ type FullNodeStruct struct {
|
|||||||
WalletBalance func(context.Context, address.Address) (types.BigInt, error) `perm:"read"`
|
WalletBalance func(context.Context, address.Address) (types.BigInt, error) `perm:"read"`
|
||||||
WalletSign func(context.Context, address.Address, []byte) (*crypto.Signature, error) `perm:"sign"`
|
WalletSign func(context.Context, address.Address, []byte) (*crypto.Signature, error) `perm:"sign"`
|
||||||
WalletSignMessage func(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) `perm:"sign"`
|
WalletSignMessage func(context.Context, address.Address, *types.Message) (*types.SignedMessage, error) `perm:"sign"`
|
||||||
WalletVerify func(context.Context, address.Address, []byte, *crypto.Signature) bool `perm:"read"`
|
WalletVerify func(context.Context, address.Address, []byte, *crypto.Signature) (bool, error) `perm:"read"`
|
||||||
WalletDefaultAddress func(context.Context) (address.Address, error) `perm:"write"`
|
WalletDefaultAddress func(context.Context) (address.Address, error) `perm:"write"`
|
||||||
WalletSetDefault func(context.Context, address.Address) error `perm:"admin"`
|
WalletSetDefault func(context.Context, address.Address) error `perm:"admin"`
|
||||||
WalletExport func(context.Context, address.Address) (*types.KeyInfo, error) `perm:"admin"`
|
WalletExport func(context.Context, address.Address) (*types.KeyInfo, error) `perm:"admin"`
|
||||||
@ -604,7 +604,7 @@ func (c *FullNodeStruct) WalletSignMessage(ctx context.Context, k address.Addres
|
|||||||
return c.Internal.WalletSignMessage(ctx, k, msg)
|
return c.Internal.WalletSignMessage(ctx, k, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *FullNodeStruct) WalletVerify(ctx context.Context, k address.Address, msg []byte, sig *crypto.Signature) bool {
|
func (c *FullNodeStruct) WalletVerify(ctx context.Context, k address.Address, msg []byte, sig *crypto.Signature) (bool, error) {
|
||||||
return c.Internal.WalletVerify(ctx, k, msg, sig)
|
return c.Internal.WalletVerify(ctx, k, msg, sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,7 +382,11 @@ var walletVerify = &cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if api.WalletVerify(ctx, addr, msg, &sig) {
|
ok, err := api.WalletVerify(ctx, addr, msg, &sig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if ok {
|
||||||
fmt.Println("valid")
|
fmt.Println("valid")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
12
extern/sector-storage/ffiwrapper/sealer_test.go
vendored
12
extern/sector-storage/ffiwrapper/sealer_test.go
vendored
@ -245,6 +245,10 @@ func TestDownloadParams(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSealAndVerify(t *testing.T) {
|
func TestSealAndVerify(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("skipping test in short mode")
|
||||||
|
}
|
||||||
|
|
||||||
defer requireFDsClosed(t, openFDs(t))
|
defer requireFDsClosed(t, openFDs(t))
|
||||||
|
|
||||||
if runtime.NumCPU() < 10 && os.Getenv("CI") == "" { // don't bother on slow hardware
|
if runtime.NumCPU() < 10 && os.Getenv("CI") == "" { // don't bother on slow hardware
|
||||||
@ -314,6 +318,10 @@ func TestSealAndVerify(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSealPoStNoCommit(t *testing.T) {
|
func TestSealPoStNoCommit(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("skipping test in short mode")
|
||||||
|
}
|
||||||
|
|
||||||
defer requireFDsClosed(t, openFDs(t))
|
defer requireFDsClosed(t, openFDs(t))
|
||||||
|
|
||||||
if runtime.NumCPU() < 10 && os.Getenv("CI") == "" { // don't bother on slow hardware
|
if runtime.NumCPU() < 10 && os.Getenv("CI") == "" { // don't bother on slow hardware
|
||||||
@ -375,6 +383,10 @@ func TestSealPoStNoCommit(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestSealAndVerify3(t *testing.T) {
|
func TestSealAndVerify3(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("skipping test in short mode")
|
||||||
|
}
|
||||||
|
|
||||||
defer requireFDsClosed(t, openFDs(t))
|
defer requireFDsClosed(t, openFDs(t))
|
||||||
|
|
||||||
if runtime.NumCPU() < 10 && os.Getenv("CI") == "" { // don't bother on slow hardware
|
if runtime.NumCPU() < 10 && os.Getenv("CI") == "" { // don't bother on slow hardware
|
||||||
|
@ -67,8 +67,8 @@ func (a *WalletAPI) WalletSignMessage(ctx context.Context, k address.Address, ms
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *WalletAPI) WalletVerify(ctx context.Context, k address.Address, msg []byte, sig *crypto.Signature) bool {
|
func (a *WalletAPI) WalletVerify(ctx context.Context, k address.Address, msg []byte, sig *crypto.Signature) (bool, error) {
|
||||||
return sigs.Verify(sig, k, msg) == nil
|
return sigs.Verify(sig, k, msg) == nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *WalletAPI) WalletDefaultAddress(ctx context.Context) (address.Address, error) {
|
func (a *WalletAPI) WalletDefaultAddress(ctx context.Context) (address.Address, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user