Example #1
0
// report validates the report arguments, sets up the required resources
// and writes the report
func report(opts *reportOpts) error {
	rep, ok := reporters[opts.reporter]
	if !ok {
		log.Println("Reporter provided is not supported. Using text")
		rep = stress.ReportText
	}

	var all stress.Results
	for _, input := range strings.Split(opts.inputf, ",") {
		in, err := file(input, false)
		if err != nil {
			return err
		}

		var results stress.Results
		if err = results.Decode(in); err != nil {
			return err
		}
		in.Close()

		all = append(all, results...)
	}
	all.Sort()

	out, err := file(opts.outputf, true)
	if err != nil {
		return err
	}
	defer out.Close()

	data, err := rep(all)
	if err != nil {
		return err
	}
	_, err = out.Write(data)

	return err
}
Example #2
0
// attack validates the attack arguments, sets up the
// required resources, launches the attack and writes the results
func attack(opts *attackOpts) error {
	if opts.rate == 0 && opts.concurrency == 0 {
		return fmt.Errorf(errRatePrefix + "or " + errConcurrencyPrefix + "can't be zero")
	} else if opts.rate != 0 && opts.concurrency != 0 {
		return fmt.Errorf(errRatePrefix + "is conflict with " + errConcurrencyPrefix)
	}

	if opts.rate != 0 && opts.duration == 0 {
		return fmt.Errorf(errDurationPrefix + "can't be zero")
	}

	if opts.concurrency != 0 && opts.number == 0 {
		return fmt.Errorf(errNumberPrefix + "can't be zero")
	}

	in, err := file(opts.targetsf, false)
	if err != nil {
		return fmt.Errorf(errTargetsFilePrefix+"(%s): %s", opts.targetsf, err)
	}
	defer in.Close()

	var body []byte
	if opts.bodyf != "" {
		bodyr, err := file(opts.bodyf, false)
		if err != nil {
			return fmt.Errorf(errBodyFilePrefix+"(%s): %s", opts.bodyf, err)
		}
		defer bodyr.Close()

		if body, err = ioutil.ReadAll(bodyr); err != nil {
			return fmt.Errorf(errBodyFilePrefix+"(%s): %s", opts.bodyf, err)
		}
	}

	targets, err := stress.NewTargetsFrom(in, body, opts.headers.Header)
	if err != nil {
		return fmt.Errorf(errTargetsFilePrefix+"(%s): %s", opts.targetsf, err)
	}
	if len(targets) == 0 {
		return fmt.Errorf(errTargetsFilePrefix + " : is empty")
	}

	switch opts.ordering {
	case "random":
		targets.Shuffle(time.Now().UnixNano())
	case "sequential":
		break
	default:
		return fmt.Errorf(errOrderingPrefix+"`%s` is invalid", opts.ordering)
	}

	out, err := file(opts.outputf, true)
	if err != nil {
		return fmt.Errorf(errOutputFilePrefix+"(%s): %s", opts.outputf, err)
	}
	defer out.Close()

	attacker := stress.NewAttacker(opts.redirects, opts.timeout, *opts.laddr.IPAddr)

	var results stress.Results
	if opts.rate != 0 {
		log.Printf(
			"Stress is attacking %d targets in %s order and %d rate for %s...\n",
			len(targets),
			opts.ordering,
			opts.rate,
			opts.duration,
		)
		results = attacker.AttackRate(targets, opts.rate, opts.duration)
	} else if opts.concurrency != 0 {
		concurrency := opts.concurrency
		if opts.concurrency > opts.number {
			concurrency = opts.number
		}
		log.Printf(
			"Stress is attacking %d targets in %s order and %d concurrency level for %d times...\n",
			len(targets),
			opts.ordering,
			concurrency,
			opts.number,
		)
		results = attacker.AttackConcy(targets, opts.concurrency, opts.number)
	}

	log.Printf("Done! Writing results to '%s'...", opts.outputf)
	err = results.Encode(out)
	if err != nil {
		return err
	}

	data, err := stress.ReportText(results)
	if err != nil {
		return err
	}

	_, err = os.Stdout.Write(data)

	return err
}