func rallyCommandAction()

in cmd/benchmark.go [248:381]


func rallyCommandAction(cmd *cobra.Command, args []string) error {
	cmd.Println("Run rally benchmarks for the package")

	variant, err := cmd.Flags().GetString(cobraext.VariantFlagName)
	if err != nil {
		return cobraext.FlagParsingError(err, cobraext.VariantFlagName)
	}

	benchName, err := cmd.Flags().GetString(cobraext.BenchNameFlagName)
	if err != nil {
		return cobraext.FlagParsingError(err, cobraext.BenchNameFlagName)
	}

	dataReindex, err := cmd.Flags().GetBool(cobraext.BenchReindexToMetricstoreFlagName)
	if err != nil {
		return cobraext.FlagParsingError(err, cobraext.BenchReindexToMetricstoreFlagName)
	}

	rallyTrackOutputDir, err := cmd.Flags().GetString(cobraext.BenchCorpusRallyTrackOutputDirFlagName)
	if err != nil {
		return cobraext.FlagParsingError(err, cobraext.BenchCorpusRallyTrackOutputDirFlagName)
	}

	rallyDryRun, err := cmd.Flags().GetBool(cobraext.BenchCorpusRallyDryRunFlagName)
	if err != nil {
		return cobraext.FlagParsingError(err, cobraext.BenchCorpusRallyDryRunFlagName)
	}

	corpusAtPath, err := cmd.Flags().GetString(cobraext.BenchCorpusRallyUseCorpusAtPathFlagName)
	if err != nil {
		return cobraext.FlagParsingError(err, cobraext.BenchCorpusRallyUseCorpusAtPathFlagName)
	}

	packageFromRegistry, err := cmd.Flags().GetString(cobraext.BenchCorpusRallyPackageFromRegistryFlagName)
	if err != nil {
		return cobraext.FlagParsingError(err, cobraext.BenchCorpusRallyPackageFromRegistryFlagName)
	}

	packageName, packageVersion, err := getPackageNameAndVersion(packageFromRegistry)
	if err != nil {
		return fmt.Errorf("getting package name and version failed, expected format: <package>-<version>: %w", err)
	}

	var packageRootPath string
	var found bool
	if len(packageName) == 0 {
		packageRootPath, found, err = packages.FindPackageRoot()
		if !found {
			return errors.New("package root not found")
		}
		if err != nil {
			return fmt.Errorf("locating package root failed: %w", err)
		}
	}

	profile, err := cobraext.GetProfileFlag(cmd)
	if err != nil {
		return err
	}

	ctx, stop := signal.Enable(cmd.Context(), logger.Info)
	defer stop()

	esClient, err := stack.NewElasticsearchClientFromProfile(profile)
	if err != nil {
		return fmt.Errorf("can't create Elasticsearch client: %w", err)
	}
	err = esClient.CheckHealth(ctx)
	if err != nil {
		return err
	}

	kc, err := stack.NewKibanaClientFromProfile(profile)
	if err != nil {
		return fmt.Errorf("can't create Kibana client: %w", err)
	}

	withOpts := []rally.OptionFunc{
		rally.WithVariant(variant),
		rally.WithBenchmarkName(benchName),
		rally.WithDataReindexing(dataReindex),
		rally.WithPackageRootPath(packageRootPath),
		rally.WithESAPI(esClient.API),
		rally.WithKibanaClient(kc),
		rally.WithProfile(profile),
		rally.WithRallyTrackOutputDir(rallyTrackOutputDir),
		rally.WithRallyDryRun(rallyDryRun),
		rally.WithRallyPackageFromRegistry(packageName, packageVersion),
		rally.WithRallyCorpusAtPath(corpusAtPath),
	}

	esMetricsClient, err := initializeESMetricsClient(ctx)
	if err != nil {
		return fmt.Errorf("can't create Elasticsearch metrics client: %w", err)
	}
	if esMetricsClient != nil {
		withOpts = append(withOpts, rally.WithESMetricsAPI(esMetricsClient.API))
	}

	runner := rally.NewRallyBenchmark(rally.NewOptions(withOpts...))

	r, err := benchrunner.Run(ctx, runner)
	if errors.Is(err, rally.ErrDryRun) {
		return nil
	}

	if err != nil {
		return fmt.Errorf("error running package rally benchmarks: %w", err)
	}

	multiReport, ok := r.(reporters.MultiReportable)
	if !ok {
		return fmt.Errorf("rally benchmark is expected to return multiple reports")
	}

	reports := multiReport.Split()
	if len(reports) != 2 {
		return fmt.Errorf("rally benchmark is expected to return a human and a file report")
	}

	// human report will always be the first
	human := reports[0]
	if err := reporters.WriteReportable(reporters.Output(outputs.ReportOutputSTDOUT), human); err != nil {
		return fmt.Errorf("error writing benchmark report: %w", err)
	}

	// file report will always be the second
	file := reports[1]
	if err := reporters.WriteReportable(reporters.Output(outputs.ReportOutputFile), file); err != nil {
		return fmt.Errorf("error writing benchmark report: %w", err)
	}

	return nil
}