diff --git a/test/e2e/generator/generate.go b/test/e2e/generator/generate.go index a0c65305faa..a898d67d8d2 100644 --- a/test/e2e/generator/generate.go +++ b/test/e2e/generator/generate.go @@ -22,7 +22,9 @@ var ( }, "validators": {"genesis", "initchain"}, } - + nodeVersions = weightedChoice{ + "": 2, + } // The following specify randomly chosen values for testnet nodes. nodeDatabases = uniformChoice{"goleveldb", "cleveldb", "rocksdb", "boltdb", "badgerdb"} ipv6 = uniformChoice{false, true} @@ -50,7 +52,10 @@ var ( ) // Generate generates random testnets using the given RNG. -func Generate(r *rand.Rand) ([]e2e.Manifest, error) { +func Generate(r *rand.Rand, multiversion string) ([]e2e.Manifest, error) { + if multiversion != "" { + nodeVersions[multiversion] = 1 + } manifests := []e2e.Manifest{} for _, opt := range combinations(testnetCombinations) { manifest, err := generateTestnet(r, opt) @@ -224,6 +229,7 @@ func generateNode( r *rand.Rand, mode e2e.Mode, syncApp bool, startAt int64, initialHeight int64, forceArchive bool, ) *e2e.ManifestNode { node := e2e.ManifestNode{ + Version: nodeVersions.Choose(r).(string), Mode: string(mode), SyncApp: syncApp, StartAt: startAt, diff --git a/test/e2e/generator/main.go b/test/e2e/generator/main.go index d5b6ab63974..16bcc1b5853 100644 --- a/test/e2e/generator/main.go +++ b/test/e2e/generator/main.go @@ -44,25 +44,31 @@ func NewCLI() *CLI { if err != nil { return err } - return cli.generate(dir, groups) + multiversion, err := cmd.Flags().GetString("multi-version") + if err != nil { + return err + } + return cli.generate(dir, groups, multiversion) }, } cli.root.PersistentFlags().StringP("dir", "d", "", "Output directory for manifests") _ = cli.root.MarkPersistentFlagRequired("dir") + cli.root.PersistentFlags().StringP("multi-version", "m", "", "Include multi-version testing."+ + "If multi-version is not specified, then only the current Tendermint version will be used in generated testnets.") cli.root.PersistentFlags().IntP("groups", "g", 0, "Number of groups") return cli } // generate generates manifests in a directory. -func (cli *CLI) generate(dir string, groups int) error { +func (cli *CLI) generate(dir string, groups int, multiversion string) error { err := os.MkdirAll(dir, 0o755) if err != nil { return err } - manifests, err := Generate(rand.New(rand.NewSource(randomSeed))) //nolint:gosec + manifests, err := Generate(rand.New(rand.NewSource(randomSeed)), multiversion) //nolint:gosec if err != nil { return err } diff --git a/test/e2e/generator/random.go b/test/e2e/generator/random.go index f21502118d7..4312eb30d70 100644 --- a/test/e2e/generator/random.go +++ b/test/e2e/generator/random.go @@ -83,3 +83,25 @@ func (usc uniformSetChoice) Choose(r *rand.Rand) []string { } return choices } + +// weightedChoice chooses a single random key from a map of keys and weights. +type weightedChoice map[interface{}]uint + +func (wc weightedChoice) Choose(r *rand.Rand) interface{} { + total := 0 + choices := make([]interface{}, 0, len(wc)) + for choice, weight := range wc { + total += int(weight) + choices = append(choices, choice) + } + + rem := r.Intn(total) + for _, choice := range choices { + rem -= int(wc[choice]) + if rem <= 0 { + return choice + } + } + + return nil +}