Example #1
0
func main() {
	// read argument from CLI
	usage := func() {
		fmt.Println("ab runs for given amount in time in seconds.")
		fmt.Println("after it ran for the given amaount of time it reports on the received requests.")
		fmt.Println("sampe use:")
		fmt.Println("$ airbiscuit 60")
		fmt.Println("GET count: 111")
		fmt.Println("POST count: 122")
	}
	if len(os.Args) != 2 {
		usage()
		return
	}
	wait, err := strconv.Atoi(os.Args[1])
	if err != nil {
		usage()
		return
	}

	// assemble the server
	s := airbiscuit.NewStats(500 * time.Millisecond)
	r := airbiscuit.Router(s)

	srv := graceful.Server{
		Timeout: 5 * time.Second,
		Server: &http.Server{
			Handler: r,
			Addr:    ":3001",
		},
	}

	// stop server after wait time
	go func() {
		time.Sleep(time.Duration(wait * int(time.Second)))
		srv.Stop(100 * time.Millisecond)
		fmt.Printf("Get count: %d\n", s.G)
		fmt.Printf("Post count: %d\n", s.P)
	}()

	srv.ListenAndServe()
}
Example #2
0
func TestIntegrationOfHttpPackage(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}

	// init
	gg.Testscenario("scenario1", endurance)

	// main part
	err := gg.ReadConfigValidate(airbiscuitLoadmodel, gogrinder.LoadmodelSchema)
	if err != nil {
		t.Fatalf("Error while reading loadmodel config: %s!", err.Error())
	}

	// start the airbiscuit server
	s := &airbiscuit.Stats{Sleep: 50 * time.Millisecond}
	r := airbiscuit.Router(s)

	srv := graceful.Server{
		Timeout: 50 * time.Millisecond,
		Server: &http.Server{
			Handler: r,
			Addr:    ":3001",
		},
	}

	// stop server after wait time
	go func() {
		time.Sleep(time.Duration(1050 * int(time.Millisecond)))
		srv.Stop(80 * time.Millisecond)
		fmt.Printf("Get count: %d\n", s.G)
		fmt.Printf("Post count: %d\n", s.P)
	}()

	go srv.ListenAndServe()

	// run the test
	start := time.Now()
	gg.Exec() // exec the scenario that has been selected in the config file
	execution := time.Now().Sub(start)

	// verify total run time of the endurance scenario
	if execution > 1100*time.Millisecond {
		t.Errorf("Error: execution time of scenario1 not as expected: %v\n", execution)
	}

	results := gg.Results("")
	// check 01_01_teststep (get requests)
	if results[0].Teststep != "01_01_teststep" {
		t.Errorf("Teststep name not as expected: %s!", results[0].Teststep)
	}
	if results[0].Count < 170 {
		t.Errorf("Less than 170 get requests: %v!", results[0].Count)
	}
	if results[0].Avg < 50.0 && results[0].Avg > 62.0 {
		t.Errorf("Average not as expected: %f!", results[0].Avg)
	}
	if results[0].Min < 50.0 && results[0].Min > 62.0 {
		t.Errorf("Minimum not as expected: %f!", results[0].Min)
	}
	if results[0].Max < 50.0 && results[0].Max > 62.0 {
		t.Errorf("Maximum not as expected: %f!", results[0].Max)
	}

	// check 02_01_teststep (post requests)
	if results[1].Teststep != "02_01_teststep" {
		t.Errorf("Teststep name not as expected: %s!", results[1].Teststep)
	}
	if results[1].Count < 170 {
		t.Errorf("Less than 170 get requests: %v!", results[1].Count)
	}
	if results[1].Avg < 50.0 && results[1].Avg > 62.0 {
		t.Errorf("Average not as expected: %f!", results[1].Avg)
	}
	if results[1].Min < 50.0 && results[1].Min > 62.0 {
		t.Errorf("Minimum not as expected: %f!", results[1].Min)
	}
	if results[1].Max < 50.0 && results[1].Max > 62.0 {
		t.Errorf("Maximum not as expected: %f!", results[1].Max)
	}
}
Example #3
0
// This is the "standard" gogrinder behaviour. If you need a special configuration
// or setup then maybe you should start with this code.
func GoGrinder(test Scenario) error {
	var err error
	filename, noExec, noReport, noFrontend, noPrometheus, jtl, port, logLevel, err := GetCLI()
	if err != nil {
		return err
	}
	ll, _ := log.ParseLevel(logLevel)
	log.SetLevel(ll)
	err = test.ReadConfig(filename)
	if err != nil {
		return err
	}

	// prepare reporter plugins
	if jtl {
		// initialize the jtl reporter
		fj, err := os.OpenFile("results.jtl", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
		if err != nil {
			log.Error("can not open jtl file: %v", err)
			// we do not need to stop in this case...
		}
		defer fj.Close()
		test.AddReportPlugin(&JtlReporter{fj})
	} else {
		// initialize the event reporter
		fe, err := os.OpenFile("event-log.txt", os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0666)
		if err != nil {
			log.Error("can not open event log file: %v", err)
		}
		defer fe.Close()
		test.AddReportPlugin(&EventReporter{fe})
	}

	// result reporter
	exec := func() {
		err = test.Exec()
		if !noReport {
			test.Report(stdout)
		}
	}

	frontend := func() {
		srv := NewTestServer(test)
		srv.Addr = fmt.Sprintf(":%d", port)
		err = srv.ListenAndServe()
	}

	// prometheus reporter needs to "wrap" all test executions
	var srv *graceful.Server
	if !noPrometheus {
		srv = NewPrometheusReporterServer()
		srv.Addr = fmt.Sprintf(":%d", 9110)
		go srv.ListenAndServe()
		// if for example the port is in use we continue...
	}

	// handle the different run modes
	// invalid mode of noExec && noFrontend is handled in cli.go
	if noExec {
		frontend()
	}
	if noFrontend {
		exec()
	}
	if !noExec && !noFrontend {
		// this is the "normal" case - webserver is blocking
		go exec()
		frontend()
	}

	// run for another +2 * scrape_interval so we read all metrics in
	if !noPrometheus {
		time.Sleep(11 * time.Second)
		srv.Stop(1 * time.Second)
	}

	return err
}