Skip to content
This repository was archived by the owner on May 13, 2022. It is now read-only.

Commit 69b2160

Browse files
authored
Merge pull request #1355 from gregdhill/ctx-tests
execution context tests
2 parents eb5192d + 702caef commit 69b2160

File tree

3 files changed

+375
-0
lines changed

3 files changed

+375
-0
lines changed
+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package contexts
2+
3+
import (
4+
"strings"
5+
"testing"
6+
7+
"github.com/hyperledger/burrow/acm"
8+
"github.com/hyperledger/burrow/acm/acmstate"
9+
"github.com/hyperledger/burrow/bcm"
10+
"github.com/hyperledger/burrow/crypto"
11+
"github.com/hyperledger/burrow/execution/exec"
12+
"github.com/hyperledger/burrow/execution/names"
13+
"github.com/hyperledger/burrow/execution/state"
14+
"github.com/hyperledger/burrow/genesis"
15+
"github.com/hyperledger/burrow/logging"
16+
"github.com/hyperledger/burrow/txs"
17+
"github.com/hyperledger/burrow/txs/payload"
18+
"github.com/stretchr/testify/require"
19+
dbm "github.com/tendermint/tm-db"
20+
)
21+
22+
func TestNameContext(t *testing.T) {
23+
accountState := acmstate.NewMemoryState()
24+
25+
privKey := newPrivKey(t)
26+
account := newAccountFromPrivKey(privKey)
27+
28+
db := dbm.NewMemDB()
29+
genesisDoc, _, _ := genesis.NewDeterministicGenesis(3450976).GenesisDoc(23, 10)
30+
blockchain := bcm.NewBlockchain(db, genesisDoc)
31+
state := state.NewState(db)
32+
33+
ctx := &NameContext{
34+
State: accountState,
35+
Logger: logging.NewNoopLogger(),
36+
Blockchain: blockchain,
37+
NameReg: names.NewCache(state),
38+
}
39+
40+
callTx := &payload.CallTx{}
41+
err := ctx.Execute(execFromTx(callTx), callTx)
42+
require.Error(t, err, "should not continue with incorrect payload")
43+
44+
nameTx := &payload.NameTx{
45+
Input: &payload.TxInput{
46+
Address: account.Address,
47+
},
48+
}
49+
50+
err = ctx.Execute(execFromTx(nameTx), nameTx)
51+
require.Error(t, err, "account should not exist")
52+
53+
accountState.Accounts[account.Address] = account
54+
nameTx.Name = "foobar"
55+
56+
err = ctx.Execute(execFromTx(nameTx), nameTx)
57+
require.Error(t, err, "insufficient amount")
58+
59+
costPerBlock := names.NameCostPerBlock(names.NameBaseCost(ctx.tx.Name, ctx.tx.Data))
60+
nameTx.Input.Amount = names.MinNameRegistrationPeriod * costPerBlock
61+
62+
err = ctx.Execute(execFromTx(nameTx), nameTx)
63+
require.NoError(t, err, "should successfully set namereg")
64+
}
65+
66+
func TestValidateStrings(t *testing.T) {
67+
nameTx := &payload.NameTx{}
68+
err := validateStrings(nameTx)
69+
require.Error(t, err, "should fail on empty name")
70+
71+
nameTx.Name = strings.Repeat("A", names.MaxNameLength+1)
72+
err = validateStrings(nameTx)
73+
require.Error(t, err, "should fail because name is too long")
74+
75+
nameTx.Name = "foo"
76+
77+
nameTx.Data = strings.Repeat("A", names.MaxDataLength+1)
78+
err = validateStrings(nameTx)
79+
require.Error(t, err, "should fail because data is too long")
80+
81+
nameTx.Data = "bar"
82+
err = validateStrings(nameTx)
83+
require.NoError(t, err, "name reg entry should be valid")
84+
}
85+
86+
func newPrivKey(t *testing.T) crypto.PrivateKey {
87+
privKey, err := crypto.GeneratePrivateKey(nil, crypto.CurveTypeEd25519)
88+
require.NoError(t, err)
89+
return privKey
90+
}
91+
92+
func newAccountFromPrivKey(privKey crypto.PrivateKey) *acm.Account {
93+
pubKey := privKey.GetPublicKey()
94+
address := pubKey.GetAddress()
95+
96+
return &acm.Account{
97+
Address: address,
98+
PublicKey: pubKey,
99+
Balance: 1337,
100+
}
101+
}
102+
103+
func execFromTx(payl payload.Payload) *exec.TxExecution {
104+
return &exec.TxExecution{
105+
Envelope: &txs.Envelope{
106+
Tx: &txs.Tx{
107+
Payload: payl,
108+
},
109+
},
110+
}
111+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package contexts
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hyperledger/burrow/acm/acmstate"
7+
"github.com/hyperledger/burrow/logging"
8+
"github.com/hyperledger/burrow/permission"
9+
"github.com/hyperledger/burrow/txs/payload"
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
func TestPermissionsContext(t *testing.T) {
14+
accountState := acmstate.NewMemoryState()
15+
16+
originPrivKey := newPrivKey(t)
17+
originAccount := newAccountFromPrivKey(originPrivKey)
18+
originAccount.Permissions.Base = permission.AllAccountPermissions.GetBase()
19+
20+
targetPrivKey := newPrivKey(t)
21+
targetAccount := newAccountFromPrivKey(targetPrivKey)
22+
23+
ctx := &PermissionsContext{
24+
State: accountState,
25+
Logger: logging.NewNoopLogger(),
26+
}
27+
28+
callTx := &payload.CallTx{}
29+
err := ctx.Execute(execFromTx(callTx), callTx)
30+
require.Error(t, err, "should not continue with incorrect payload")
31+
32+
permsTx := &payload.PermsTx{
33+
Input: &payload.TxInput{
34+
Address: originAccount.Address,
35+
},
36+
}
37+
38+
err = ctx.Execute(execFromTx(permsTx), permsTx)
39+
require.Error(t, err, "account should not exist")
40+
41+
accountState.Accounts[originAccount.Address] = originAccount
42+
accountState.Accounts[targetAccount.Address] = targetAccount
43+
44+
value := true
45+
tests := []struct {
46+
args permission.PermArgs
47+
exp func(t *testing.T, err error)
48+
}{
49+
{
50+
args: permission.PermArgs{
51+
Action: 1337,
52+
Target: &targetAccount.Address,
53+
Permission: ptrPermFlag(permission.SetBase),
54+
Value: &value,
55+
},
56+
exp: errCallback(func(t *testing.T, err error) {
57+
require.Error(t, err, "should error with unknown action")
58+
}),
59+
},
60+
{
61+
args: permission.PermArgs{
62+
Action: permission.SetBase,
63+
Target: &targetAccount.Address,
64+
Permission: ptrPermFlag(permission.SetBase),
65+
Value: &value,
66+
},
67+
exp: errCallback(func(t *testing.T, err error) {
68+
require.NoError(t, err)
69+
}),
70+
},
71+
{
72+
args: permission.PermArgs{
73+
Action: permission.UnsetBase,
74+
Target: &targetAccount.Address,
75+
Permission: ptrPermFlag(permission.UnsetBase),
76+
Value: &value,
77+
},
78+
exp: errCallback(func(t *testing.T, err error) {
79+
require.NoError(t, err)
80+
}),
81+
},
82+
{
83+
args: permission.PermArgs{
84+
Action: permission.AddRole,
85+
Target: &targetAccount.Address,
86+
Permission: ptrPermFlag(permission.AddRole),
87+
Value: &value,
88+
Role: ptrRoleString(permission.BondString),
89+
},
90+
exp: errCallback(func(t *testing.T, err error) {
91+
require.NoError(t, err)
92+
}),
93+
},
94+
{
95+
args: permission.PermArgs{
96+
Action: permission.RemoveRole,
97+
Target: &targetAccount.Address,
98+
Permission: ptrPermFlag(permission.RemoveRole),
99+
Value: &value,
100+
Role: ptrRoleString(permission.BondString),
101+
},
102+
exp: errCallback(func(t *testing.T, err error) {
103+
require.NoError(t, err)
104+
}),
105+
},
106+
{
107+
args: permission.PermArgs{
108+
Action: permission.RemoveRole,
109+
Target: &targetAccount.Address,
110+
Permission: ptrPermFlag(permission.RemoveRole),
111+
Value: &value,
112+
Role: ptrRoleString(permission.BondString),
113+
},
114+
exp: errCallback(func(t *testing.T, err error) {
115+
require.Error(t, err, "can't remove role that isn't set")
116+
}),
117+
},
118+
}
119+
120+
for _, tt := range tests {
121+
permsTx.PermArgs = tt.args
122+
err = ctx.Execute(execFromTx(permsTx), permsTx)
123+
tt.exp(t, err)
124+
}
125+
}
126+
127+
func ptrPermFlag(flag permission.PermFlag) *permission.PermFlag {
128+
return &flag
129+
}
130+
131+
func ptrRoleString(role string) *string {
132+
return &role
133+
}
134+
135+
func errCallback(condition func(t *testing.T, err error)) func(t *testing.T, err error) {
136+
return func(t *testing.T, err error) {
137+
condition(t, err)
138+
}
139+
}
+125
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package contexts
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hyperledger/burrow/acm/acmstate"
7+
"github.com/hyperledger/burrow/logging"
8+
"github.com/hyperledger/burrow/txs/payload"
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func TestSendContext(t *testing.T) {
13+
accountState := acmstate.NewMemoryState()
14+
15+
originPrivKey := newPrivKey(t)
16+
originAccount := newAccountFromPrivKey(originPrivKey)
17+
18+
targetPrivKey := newPrivKey(t)
19+
targetAccount := newAccountFromPrivKey(targetPrivKey)
20+
21+
ctx := &SendContext{
22+
State: accountState,
23+
Logger: logging.NewNoopLogger(),
24+
}
25+
26+
callTx := &payload.CallTx{}
27+
err := ctx.Execute(execFromTx(callTx), callTx)
28+
require.Error(t, err, "should not continue with incorrect payload")
29+
30+
accountState.Accounts[originAccount.Address] = originAccount
31+
accountState.Accounts[targetAccount.Address] = targetAccount
32+
33+
tests := []struct {
34+
tx *payload.SendTx
35+
exp func(t *testing.T, err error)
36+
}{
37+
{
38+
tx: &payload.SendTx{
39+
Inputs: []*payload.TxInput{
40+
&payload.TxInput{
41+
Address: originAccount.Address,
42+
},
43+
},
44+
},
45+
exp: errCallback(func(t *testing.T, err error) {
46+
require.Error(t, err, "should not allow zero payment")
47+
}),
48+
},
49+
{
50+
tx: &payload.SendTx{
51+
Inputs: []*payload.TxInput{
52+
&payload.TxInput{
53+
Address: originAccount.Address,
54+
Amount: 100,
55+
},
56+
},
57+
},
58+
exp: errCallback(func(t *testing.T, err error) {
59+
require.Error(t, err, "should not allow overpayment (i.e. inputs > outputs)")
60+
}),
61+
},
62+
{
63+
tx: &payload.SendTx{
64+
Inputs: []*payload.TxInput{
65+
&payload.TxInput{
66+
Address: originAccount.Address,
67+
Amount: 100,
68+
},
69+
},
70+
Outputs: []*payload.TxOutput{
71+
&payload.TxOutput{
72+
Address: originAccount.Address,
73+
Amount: 100,
74+
},
75+
},
76+
},
77+
exp: errCallback(func(t *testing.T, err error) {
78+
require.Error(t, err, "should not allow self payment")
79+
}),
80+
},
81+
{
82+
tx: &payload.SendTx{
83+
Inputs: []*payload.TxInput{
84+
&payload.TxInput{
85+
Address: originAccount.Address,
86+
Amount: 100,
87+
},
88+
},
89+
Outputs: []*payload.TxOutput{
90+
&payload.TxOutput{
91+
Address: targetAccount.Address,
92+
Amount: 100,
93+
},
94+
},
95+
},
96+
exp: errCallback(func(t *testing.T, err error) {
97+
require.NoError(t, err, "should allow payment")
98+
}),
99+
},
100+
{
101+
tx: &payload.SendTx{
102+
Inputs: []*payload.TxInput{
103+
&payload.TxInput{
104+
Address: originAccount.Address,
105+
Amount: 10000,
106+
},
107+
},
108+
Outputs: []*payload.TxOutput{
109+
&payload.TxOutput{
110+
Address: targetAccount.Address,
111+
Amount: 10000,
112+
},
113+
},
114+
},
115+
exp: errCallback(func(t *testing.T, err error) {
116+
require.Error(t, err, "should not allow send with insufficient funds")
117+
}),
118+
},
119+
}
120+
121+
for _, tt := range tests {
122+
err = ctx.Execute(execFromTx(tt.tx), tt.tx)
123+
tt.exp(t, err)
124+
}
125+
}

0 commit comments

Comments
 (0)