Skip to content

Commit

Permalink
test: executeParameterChange2, validateProposalState, checkProposalVa…
Browse files Browse the repository at this point in the history
…lidation
  • Loading branch information
notJoon committed Dec 23, 2024
1 parent 7d0de57 commit a3451d8
Show file tree
Hide file tree
Showing 2 changed files with 291 additions and 9 deletions.
84 changes: 84 additions & 0 deletions gov/governance/execute2.gno
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ package governance

import (
"errors"
"std"
"strconv"
"strings"
"time"

"gno.land/p/demo/avl"
"gno.land/p/demo/ufmt"
"gno.land/r/gnoswap/v1/common"
cp "gno.land/r/gnoswap/v1/community_pool"
"gno.land/r/gnoswap/v1/consts"
en "gno.land/r/gnoswap/v1/emission"
pl "gno.land/r/gnoswap/v1/pool"
)

var (
Expand Down Expand Up @@ -107,6 +112,56 @@ func parseMessage(msg string) (pkgPath string, function string, params []string,
return parts[0], parts[1], strings.Split(parts[2], ","), nil
}

func createParameterHandlers() *ParameterRegistry {
registry := NewParameterRegistry()

// Community pool
registry.Register(consts.COMMUNITY_POOL_PATH, "TransferToken", func(params []string) error {
if len(params) != 3 {
return ufmt.Errorf("invalid parameters for TransferToken. expected 3 but got %d", len(params))
}
cp.TransferToken(params[0], std.Address(params[1]), parseUint64(params[2]))
return nil
})

// Emission
registry.Register(consts.EMISSION_PATH, "ChangeDistributionPct", func(params []string) error {
if len(params) != 8 {
return ufmt.Errorf("invalid parameters for ChangeDistributionPct. expected 8 but got %d", len(params))
}
en.ChangeDistributionPct(
parseInt(params[0]),
parseUint64(params[1]),
parseInt(params[2]),
parseUint64(params[3]),
parseInt(params[4]),
parseUint64(params[5]),
parseInt(params[6]),
parseUint64(params[7]),
)
return nil
})

// Pool
registry.Register(consts.POOL_PATH, "SetFeeProtocol", func(params []string) error {
if len(params) != 2 {
return ufmt.Errorf("invalid parameters for SetFeeProtocol. expected 2 but got %d", len(params))
}
pl.SetFeeProtocol(uint8(parseUint64(params[0])), uint8(parseUint64(params[1])))
return nil
})

registry.Register(consts.POOL_PATH, "SetPoolCreationFee", func(params []string) error {
if len(params) != 1 {
return ufmt.Errorf("invalid parameters for SetPoolCreationFee. expected 1 but got %d", len(params))
}
pl.SetPoolCreationFee(parseUint64(params[0]))
return nil
})

return registry
}

///////////////////// VALIDATION /////////////////////

type ExecutionValidator struct {
Expand Down Expand Up @@ -213,3 +268,32 @@ func validateExecutionWindow(now, windowStart, windowEnd uint64) error {

return nil
}

///////////////////// UTILS /////////////////////

func parseInt(s string) int {
num, err := strconv.ParseInt(s, 10, 64)
if err != nil {
panic(ufmt.Sprintf("invalid int value: %s", s))
}
return int(num)
}

func parseUint64(s string) uint64 {
num, err := strconv.ParseUint(s, 10, 64)
if err != nil {
panic(ufmt.Sprintf("invalid uint64 value: %s", s))
}
return num
}

func parseBool(s string) bool {
switch s {
case "true":
return true
case "false":
return false
default:
panic(ufmt.Sprintf("invalid bool value: %s", s))
}
}
216 changes: 207 additions & 9 deletions gov/governance/execute2_test.gno
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package governance

import (
"errors"
"std"
"testing"

"gno.land/p/demo/uassert"
)

func TestParameterRegistry(t *testing.T) {
Expand Down Expand Up @@ -46,20 +50,214 @@ func TestParameterRegistry(t *testing.T) {
handler, err := registry.Handler(tt.pkgPath, tt.function)

if tt.wantErr {
if err == nil {
t.Errorf("expected error but got nil")
}
if err.Error() != tt.errMessage {
t.Errorf("expected error message %q but got %q", tt.errMessage, err.Error())
}
uassert.Error(t, err, tt.errMessage)
uassert.Equal(t, err.Error(), tt.errMessage)
} else {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
uassert.NoError(t, err)
if handler == nil {
t.Error("expected handler to be non-nil")
}
}
})
}
}

func TestExecuteParameterChange2(t *testing.T) {
registry := NewParameterRegistry()

registry.Register("test/pkg", "TestFunc", func(params []string) error {
if len(params) != 2 {
return errors.New("invalid params length")
}
return nil
})

tests := []struct {
name string
msgs []string
wantErr bool
}{
{
name: "Pass: Valid message",
msgs: []string{
"test/pkg*EXE*TestFunc*EXE*param1,param2",
},
wantErr: false,
},
{
name: "Fail: Missing separator",
msgs: []string{
"test/pkg*EXE*TestFunc",
},
wantErr: true,
},
{
name: "Fail: Non-existent handler",
msgs: []string{
"unknown/pkg*EXE*UnknownFunc*EXE*param1",
},
wantErr: true,
},
{
name: "Fail: Not enough parameters",
msgs: []string{
"test/pkg*EXE*TestFunc*EXE*param1",
},
wantErr: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := executeParameterChange2(tt.msgs, registry)
if (err != nil) != tt.wantErr {
t.Errorf("executeParameterChange2() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

func TestValidateProposalState(t *testing.T) {
tests := []struct {
name string
proposal *ProposalInfo
want ExecutionValidator
}{
{
name: "Pass: Text proposal",
proposal: &ProposalInfo{
ProposalType: "TEXT",
ExecutionState: ExecutionState{
Executed: false,
Canceled: false,
Rejected: false,
Passed: true,
},
},
want: ExecutionValidator{
isTextProposal: true,
isAlreadyExecuted: false,
isAlreadyCanceled: false,
isAlreadyRejected: false,
hasPassed: true,
},
},
{
name: "Pass: Already executed",
proposal: &ProposalInfo{
ProposalType: "PARAMETER_CHANGE",
ExecutionState: ExecutionState{
Executed: true,
Canceled: false,
Rejected: false,
Passed: true,
},
},
want: ExecutionValidator{
isTextProposal: false,
isAlreadyExecuted: true,
isAlreadyCanceled: false,
isAlreadyRejected: false,
hasPassed: true,
},
},
{
name: "Pass: Canceled",
proposal: &ProposalInfo{
ProposalType: "PARAMETER_CHANGE",
ExecutionState: ExecutionState{
Executed: false,
Canceled: true,
Rejected: false,
Passed: false,
},
},
want: ExecutionValidator{
isTextProposal: false,
isAlreadyExecuted: false,
isAlreadyCanceled: true,
isAlreadyRejected: false,
hasPassed: false,
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := validateProposalState(tt.proposal)
if got != tt.want {
t.Errorf("validateProposalState() = %v, want %v", got, tt.want)
}
})
}
}

func TestCheckProposalValidation(t *testing.T) {
// TODO: change error message after error code is defined
tests := []struct {
name string
validator ExecutionValidator
wantErr bool
errMsg string
}{
{
name: "Pass: Valid proposal",
validator: ExecutionValidator{
isTextProposal: false,
isAlreadyExecuted: false,
isAlreadyCanceled: false,
isAlreadyRejected: false,
hasPassed: true,
},
wantErr: false,
},
{
name: "Fail: Text proposal is not executable",
validator: ExecutionValidator{
isTextProposal: true,
isAlreadyExecuted: false,
isAlreadyCanceled: false,
isAlreadyRejected: false,
hasPassed: true,
},
wantErr: true,
errMsg: "[GNOSWAP-GOVERNANCE-014] can not execute text proposal",
},
{
name: "Fail: Already executed, canceled, or rejected",
validator: ExecutionValidator{
isTextProposal: false,
isAlreadyExecuted: true,
isAlreadyCanceled: false,
isAlreadyRejected: false,
hasPassed: true,
},
wantErr: true,
errMsg: "proposal already executed, canceled, or rejected",
},
{
name: "Fail: Proposal has not passed",
validator: ExecutionValidator{
isTextProposal: false,
isAlreadyExecuted: false,
isAlreadyCanceled: false,
isAlreadyRejected: false,
hasPassed: false,
},
wantErr: true,
errMsg: "proposal has not passed",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := checkProposalValidation(tt.validator)
if tt.wantErr {
uassert.Error(t, err, tt.errMsg)
uassert.Equal(t, err.Error(), tt.errMsg)
} else {
uassert.NoError(t, err)
}
})
}
}

0 comments on commit a3451d8

Please sign in to comment.