operations functions
This commit is contained in:
parent
4970754338
commit
1ee6c3295d
|
@ -8,9 +8,6 @@ import (
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RandSetup performs the random setup the mock module needs.
|
|
||||||
type RandSetup func(r *rand.Rand, accounts []Account)
|
|
||||||
|
|
||||||
// Operation runs a state machine transition, and ensures the transition
|
// Operation runs a state machine transition, and ensures the transition
|
||||||
// happened as expected. The operation could be running and testing a fuzzed
|
// happened as expected. The operation could be running and testing a fuzzed
|
||||||
// transaction, or doing the same for a message.
|
// transaction, or doing the same for a message.
|
||||||
|
@ -24,6 +21,9 @@ type Operation func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||||
accounts []Account, event func(string)) (
|
accounts []Account, event func(string)) (
|
||||||
action string, futureOperations []FutureOperation, err error)
|
action string, futureOperations []FutureOperation, err error)
|
||||||
|
|
||||||
|
// queue of operations
|
||||||
|
type OperationQueue map[int][]Operation
|
||||||
|
|
||||||
// FutureOperation is an operation which will be ran at the beginning of the
|
// FutureOperation is an operation which will be ran at the beginning of the
|
||||||
// provided BlockHeight. If both a BlockHeight and BlockTime are specified, it
|
// provided BlockHeight. If both a BlockHeight and BlockTime are specified, it
|
||||||
// will use the BlockHeight. In the (likely) event that multiple operations
|
// will use the BlockHeight. In the (likely) event that multiple operations
|
||||||
|
@ -40,3 +40,31 @@ type WeightedOperation struct {
|
||||||
Weight int
|
Weight int
|
||||||
Op Operation
|
Op Operation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WeightedOperations is the group of all weighted operations to simulate.
|
||||||
|
type WeightedOperations []WeightedOperation
|
||||||
|
|
||||||
|
func (w WeightedOperations) totalWeight() int {
|
||||||
|
totalOpWeight := 0
|
||||||
|
for i := 0; i < len(w); i++ {
|
||||||
|
totalOpWeight += w[i].Weight
|
||||||
|
}
|
||||||
|
return totalOpWeight
|
||||||
|
}
|
||||||
|
|
||||||
|
type selectOpFn func(r *rand.Rand) Operation
|
||||||
|
|
||||||
|
func (w WeightedOperations) getSelectOpFn() selectOpFn {
|
||||||
|
totalOpWeight := ops.totalWeight()
|
||||||
|
return func(r *rand.Rand) Operation {
|
||||||
|
x := r.Intn(totalOpWeight)
|
||||||
|
for i := 0; i < len(ops); i++ {
|
||||||
|
if x <= ops[i].Weight {
|
||||||
|
return ops[i].Op
|
||||||
|
}
|
||||||
|
x -= ops[i].Weight
|
||||||
|
}
|
||||||
|
// shouldn't happen
|
||||||
|
return ops[0].Op
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,9 @@ import (
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// RandSetup performs the random setup the mock module needs.
|
||||||
|
type RandSetup func(r *rand.Rand, accounts []Account)
|
||||||
|
|
||||||
// Simulate tests application by sending random messages.
|
// Simulate tests application by sending random messages.
|
||||||
func Simulate(t *testing.T, app *baseapp.BaseApp,
|
func Simulate(t *testing.T, app *baseapp.BaseApp,
|
||||||
appStateFn func(r *rand.Rand, accs []Account) json.RawMessage,
|
appStateFn func(r *rand.Rand, accs []Account) json.RawMessage,
|
||||||
|
@ -27,26 +30,25 @@ func Simulate(t *testing.T, app *baseapp.BaseApp,
|
||||||
invariants []Invariant, numBlocks int, blockSize int, commit bool) error {
|
invariants []Invariant, numBlocks int, blockSize int, commit bool) error {
|
||||||
|
|
||||||
time := time.Now().UnixNano()
|
time := time.Now().UnixNano()
|
||||||
return SimulateFromSeed(t, app, appStateFn, time, ops, setups, invariants, numBlocks, blockSize, commit)
|
return SimulateFromSeed(t, app, appStateFn, time, ops,
|
||||||
|
setups, invariants, numBlocks, blockSize, commit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initialize the chain for the simulation
|
||||||
func initChain(r *rand.Rand, params Params,
|
func initChain(r *rand.Rand, params Params,
|
||||||
accounts []Account, setups []RandSetup, app *baseapp.BaseApp,
|
accounts []Account, setups []RandSetup, app *baseapp.BaseApp,
|
||||||
appStateFn func(r *rand.Rand, accounts []Account) json.RawMessage) (
|
appStateFn func(r *rand.Rand, accounts []Account) json.RawMessage) mockValidators {
|
||||||
validators map[string]mockValidator) {
|
|
||||||
|
|
||||||
res := app.InitChain(abci.RequestInitChain{AppStateBytes: appStateFn(r, accounts)})
|
req := abci.RequestInitChain{
|
||||||
validators = make(map[string]mockValidator)
|
AppStateBytes: appStateFn(r, accounts),
|
||||||
for _, validator := range res.Validators {
|
|
||||||
str := fmt.Sprintf("%v", validator.PubKey)
|
|
||||||
validators[str] = mockValidator{validator, GetMemberOfInitialState(r, params.InitialLivenessWeightings)}
|
|
||||||
}
|
}
|
||||||
|
res := app.InitChain(req)
|
||||||
|
validators = newMockValidators(res.Validators)
|
||||||
|
|
||||||
for i := 0; i < len(setups); i++ {
|
for i := 0; i < len(setups); i++ {
|
||||||
setups[i](r, accounts)
|
setups[i](r, accounts)
|
||||||
}
|
}
|
||||||
|
return validators
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SimulateFromSeed tests an application by running the provided
|
// SimulateFromSeed tests an application by running the provided
|
||||||
|
@ -230,31 +232,16 @@ func SimulateFromSeed(tb testing.TB, app *baseapp.BaseApp,
|
||||||
type blockSimFn func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
type blockSimFn func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||||
accounts []Account, header abci.Header, logWriter func(string)) (opCount int)
|
accounts []Account, header abci.Header, logWriter func(string)) (opCount int)
|
||||||
|
|
||||||
// Returns a function to simulate blocks. Written like this to avoid constant parameters being passed everytime, to minimize
|
// Returns a function to simulate blocks. Written like this to avoid constant
|
||||||
// memory overhead
|
// parameters being passed everytime, to minimize memory overhead
|
||||||
func createBlockSimulator(testingMode bool, tb testing.TB, t *testing.T, params Params,
|
func createBlockSimulator(testingMode bool, tb testing.TB, t *testing.T, params Params,
|
||||||
event func(string), invariants []Invariant, ops []WeightedOperation,
|
event func(string), invariants []Invariant, ops WeightedOperations,
|
||||||
operationQueue map[int][]Operation, timeOperationQueue []FutureOperation,
|
operationQueue map[int][]Operation, timeOperationQueue []FutureOperation,
|
||||||
totalNumBlocks int, avgBlockSize int, displayLogs func()) blockSimFn {
|
totalNumBlocks int, avgBlockSize int, displayLogs func()) blockSimFn {
|
||||||
|
|
||||||
var lastBlocksizeState = 0 // state for [4 * uniform distribution]
|
var lastBlocksizeState = 0 // state for [4 * uniform distribution]
|
||||||
var totalOpWeight = 0
|
|
||||||
var blocksize int
|
var blocksize int
|
||||||
|
selectOp := ops.getSelectOpFn()
|
||||||
for i := 0; i < len(ops); i++ {
|
|
||||||
totalOpWeight += ops[i].Weight
|
|
||||||
}
|
|
||||||
selectOp := func(r *rand.Rand) Operation {
|
|
||||||
x := r.Intn(totalOpWeight)
|
|
||||||
for i := 0; i < len(ops); i++ {
|
|
||||||
if x <= ops[i].Weight {
|
|
||||||
return ops[i].Op
|
|
||||||
}
|
|
||||||
x -= ops[i].Weight
|
|
||||||
}
|
|
||||||
// shouldn't happen
|
|
||||||
return ops[0].Op
|
|
||||||
}
|
|
||||||
|
|
||||||
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
return func(r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
|
||||||
accounts []Account, header abci.Header, logWriter func(string)) (opCount int) {
|
accounts []Account, header abci.Header, logWriter func(string)) (opCount int) {
|
||||||
|
|
|
@ -16,6 +16,26 @@ type mockValidator struct {
|
||||||
livenessState int
|
livenessState int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type mockValidators map[string]mockValidator
|
||||||
|
|
||||||
|
// get mockValidators from abci validators
|
||||||
|
func newMockValidators(abciVals abci.ValidatorUpdate) mockValidators {
|
||||||
|
|
||||||
|
validators = make(mockValidators)
|
||||||
|
for _, validator := range abciVals {
|
||||||
|
str := fmt.Sprintf("%v", validator.PubKey)
|
||||||
|
liveliness := GetMemberOfInitialState(r,
|
||||||
|
params.InitialLivenessWeightings)
|
||||||
|
|
||||||
|
validators[str] = mockValidator{
|
||||||
|
val: validator,
|
||||||
|
livenessState: liveliness,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return validators
|
||||||
|
}
|
||||||
|
|
||||||
// TODO describe usage
|
// TODO describe usage
|
||||||
func getKeys(validators map[string]mockValidator) []string {
|
func getKeys(validators map[string]mockValidator) []string {
|
||||||
keys := make([]string, len(validators))
|
keys := make([]string, len(validators))
|
||||||
|
|
Loading…
Reference in New Issue