You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
2.6 KiB

  1. //nolint: gosec
  2. package main
  3. import (
  4. "context"
  5. "fmt"
  6. stdlog "log"
  7. "math/rand"
  8. "os"
  9. "path/filepath"
  10. "github.com/spf13/cobra"
  11. "github.com/tendermint/tendermint/libs/log"
  12. e2e "github.com/tendermint/tendermint/test/e2e/pkg"
  13. )
  14. const (
  15. randomSeed int64 = 4827085738
  16. )
  17. func main() {
  18. ctx, cancel := context.WithCancel(context.Background())
  19. defer cancel()
  20. cli, err := NewCLI()
  21. if err != nil {
  22. stdlog.Fatal(err)
  23. }
  24. cli.Run(ctx)
  25. }
  26. // CLI is the Cobra-based command-line interface.
  27. type CLI struct {
  28. root *cobra.Command
  29. opts Options
  30. logger log.Logger
  31. }
  32. // NewCLI sets up the CLI.
  33. func NewCLI() (*CLI, error) {
  34. logger, err := log.NewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo)
  35. if err != nil {
  36. return nil, err
  37. }
  38. cli := &CLI{
  39. logger: logger,
  40. }
  41. cli.root = &cobra.Command{
  42. Use: "generator",
  43. Short: "End-to-end testnet generator",
  44. SilenceUsage: true,
  45. SilenceErrors: true, // we'll output them ourselves in Run()
  46. RunE: func(cmd *cobra.Command, args []string) error {
  47. return cli.generate()
  48. },
  49. }
  50. cli.root.PersistentFlags().StringVarP(&cli.opts.Directory, "dir", "d", "", "Output directory for manifests")
  51. _ = cli.root.MarkPersistentFlagRequired("dir")
  52. cli.root.Flags().BoolVarP(&cli.opts.Reverse, "reverse", "r", false, "Reverse sort order")
  53. cli.root.PersistentFlags().IntVarP(&cli.opts.NumGroups, "groups", "g", 0, "Number of groups")
  54. cli.root.PersistentFlags().IntVarP(&cli.opts.MinNetworkSize, "min-size", "", 1,
  55. "Minimum network size (nodes)")
  56. cli.root.PersistentFlags().IntVarP(&cli.opts.MaxNetworkSize, "max-size", "", 0,
  57. "Maxmum network size (nodes), 0 is unlimited")
  58. return cli, nil
  59. }
  60. // generate generates manifests in a directory.
  61. func (cli *CLI) generate() error {
  62. err := os.MkdirAll(cli.opts.Directory, 0755)
  63. if err != nil {
  64. return err
  65. }
  66. manifests, err := Generate(rand.New(rand.NewSource(randomSeed)), cli.opts)
  67. if err != nil {
  68. return err
  69. }
  70. switch {
  71. case cli.opts.NumGroups <= 0:
  72. e2e.SortManifests(manifests, cli.opts.Reverse)
  73. if err := e2e.WriteManifests(filepath.Join(cli.opts.Directory, "gen"), manifests); err != nil {
  74. return err
  75. }
  76. default:
  77. groupManifests := e2e.SplitGroups(cli.opts.NumGroups, manifests)
  78. for idx, gm := range groupManifests {
  79. e2e.SortManifests(gm, cli.opts.Reverse)
  80. prefix := filepath.Join(cli.opts.Directory, fmt.Sprintf("gen-group%02d", idx))
  81. if err := e2e.WriteManifests(prefix, gm); err != nil {
  82. return err
  83. }
  84. }
  85. }
  86. return nil
  87. }
  88. // Run runs the CLI.
  89. func (cli *CLI) Run(ctx context.Context) {
  90. if err := cli.root.ExecuteContext(ctx); err != nil {
  91. cli.logger.Error(err.Error())
  92. os.Exit(1)
  93. }
  94. }