operations functions

This commit is contained in:
rigelrozanski 2018-11-07 23:26:02 -05:00
parent 4970754338
commit 1ee6c3295d
3 changed files with 67 additions and 32 deletions

View File

@ -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
}
}

View File

@ -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) {

View File

@ -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))