Beispiel #1
0
func TestParser(t *testing.T) {
	for _, tt := range bTests {
		b, _ := parse.ParseLine(tt.line)
		name, arg, _, _ := parseNameArgThread(b.Name)
		if name != tt.name {
			t.Errorf("parseNameArgThread(%s): expected %s, actual %s", b.Name, tt.name, name)
		}
		if arg != tt.arg {
			t.Errorf("parseNameArgThread(%s): expected %s, actual %s", b.Name, tt.arg, arg)
		}
		if b.NsPerOp != tt.nsperop {
			t.Errorf("parseNameArgThread(%s): expected %f, actual %f", b.Name, tt.nsperop, b.NsPerOp)
		}
	}
}
Beispiel #2
0
func (b *benchRunner) run() error {
	stderrPipe, err := b.cmd.StderrPipe()
	if err != nil {
		return err
	}
	stderrReader := io.TeeReader(stderrPipe, os.Stderr)
	stdoutPipe, err := b.cmd.StdoutPipe()
	if err != nil {
		return err
	}
	stdoutReader := io.TeeReader(stdoutPipe, os.Stderr)
	reader := io.MultiReader(stdoutReader, stderrReader)
	if err := b.cmd.Start(); err != nil {
		return err
	}
	out, err := ioutil.ReadAll(reader)
	if err != nil {
		return err
	}
	err = b.cmd.Wait()
	if err != nil {
		return err
	}
	outs := strings.Split(string(out), "\n")
	b.output = make([]float64, len(benchmarks))
	for _, s := range outs {
		if !strings.HasPrefix(s, "Benchmark") {
			continue
		}
		res, err := parse.ParseLine(s)
		if err != nil {
			return err
		}
		name := strings.Split(res.Name, "-")[0]
		for i, benchmark := range benchmarks {
			if benchmark.name == name {
				b.output[i] = res.NsPerOp
			}
		}
	}
	fmt.Fprintf(os.Stderr, "%#v\n", b.output)
	return nil
}
Beispiel #3
0
func main() {
	flag.Parse()
	if *format != "xml" && *format != "json" {
		log.Fatalf("Unsupported output format: %q", *format)
	}

	r, w, err := os.Pipe()
	if err != nil {
		log.Fatal(err)
	}

	go func() {
		if _, err := io.Copy(io.MultiWriter(w, os.Stderr), os.Stdin); err != nil {
			log.Fatal(err)
		}
		if err := w.Close(); err != nil {
			log.Fatal(err)
		}
	}()

	var (
		results  []*testCase
		lastTest *testCase

		benchmarks []*parse.Benchmark
	)

	s := bufio.NewScanner(r)
	for s.Scan() {
		if err := s.Err(); err == io.EOF {
			break
		} else if err != nil {
			log.Fatal(err)
		}

		ss := testCaseRE.FindStringSubmatch(s.Text())
		if len(ss) > 0 {
			if fixed := strings.TrimSuffix(ss[3], " seconds"); fixed != ss[3] {
				// Before
				// https://github.com/golang/go/commit/0e92b538a9f6e337b8e48f47f38803e8245c03cc,
				// this duration format wasn't compatible with time.ParseDuration.  This
				// works around the difference.
				ss[3] = fixed + "s"
			}
			dur, err := time.ParseDuration(ss[3])
			if err != nil {
				log.Fatal(err)
			}
			lastTest = &testCase{
				Name:     ss[2],
				Duration: dur,
				Status:   status(ss[1]),
			}
			results = append(results, lastTest)
		} else if lastTest != nil && strings.HasPrefix(s.Text(), logPrefix) {
			lastTest.Log = append(lastTest.Log, strings.TrimPrefix(s.Text(), logPrefix))
		} else {
			lastTest = nil

			if strings.HasPrefix(s.Text(), "Benchmark") {
				b, err := parse.ParseLine(s.Text())
				if err != nil {
					log.Fatal(err)
				}
				benchmarks = append(benchmarks, b)
			}
		}
	}

	f, err := os.Create(*outputFile)
	if err != nil {
		log.Fatalf("Failure to create output file %q: %v", *outputFile, err)
	}

	switch *format {
	case "xml":
		if err := xml.NewEncoder(f).EncodeElement(makeTestSuite(results, benchmarks), xml.StartElement{
			Name: xml.Name{Local: "testsuite"},
		}); err != nil {
			log.Fatalf("Error encoding XML: %v", err)
		}
	case "json":
		if err := json.NewEncoder(f).Encode(struct {
			Tests      []*testCase
			Benchmarks []*parse.Benchmark `json:",omitempty"`
		}{results, benchmarks}); err != nil {
			log.Fatalf("Error encoding JSON: %v", err)
		}
	default:
		panic("unsupported output format: " + *format)
	}

	if err := f.Close(); err != nil {
		log.Fatalf("Error closing output file %q: %v", *outputFile, err)
	}
}
Beispiel #4
0
func main() {

	var oBenchNames, oBenchArgs stringList

	// graph elements will be ordered as in benchmark output by default - unless the order was specified here
	flag.Var(&oBenchNames, "obn", "comma-separated list of benchmark names")
	flag.Var(&oBenchArgs, "oba", "comma-separated list of benchmark arguments")
	title := flag.String("title", "Graph: Benchmark results in ns/op", "title of a graph")
	apiUrl := flag.String("apiurl", "http://benchgraph.codingberg.com", "url to server api")
	flag.Parse()

	var skipBenchNamesParsing, skipBenchArgsParsing bool

	if oBenchNames.Len() > 0 {
		skipBenchNamesParsing = true
	}
	if oBenchArgs.Len() > 0 {
		skipBenchArgsParsing = true
	}

	benchResults := make(BenchNameSet)

	// parse Golang benchmark results, line by line
	scan := bufio.NewScanner(os.Stdin)
	green := color.New(color.FgGreen).SprintfFunc()
	red := color.New(color.FgRed).SprintFunc()
	for scan.Scan() {
		line := scan.Text()

		mark := green("√")

		b, err := parse.ParseLine(line)
		if err != nil {
			mark = red("?")
		}

		// read bench name and arguments
		if b != nil {
			name, arg, _, err := parseNameArgThread(b.Name)
			if err != nil {
				mark = red("!")
				fmt.Printf("%s %s\n", mark, line)
				continue
			}

			if !skipBenchNamesParsing && !oBenchNames.stringInList(name) {
				oBenchNames.Add(name)
			}

			if !skipBenchArgsParsing && !oBenchArgs.stringInList(arg) {
				oBenchArgs.Add(arg)
			}

			if _, ok := benchResults[name]; !ok {
				benchResults[name] = make(BenchArgSet)
			}

			benchResults[name][arg] = b.NsPerOp
		}

		fmt.Printf("%s %s\n", mark, line)
	}

	if err := scan.Err(); err != nil {
		fmt.Fprintf(os.Stderr, "reading standard input: %v", err)
		os.Exit(1)
	}

	if len(benchResults) == 0 {
		fmt.Fprintf(os.Stderr, "no data to show.\n\n")
		os.Exit(1)
	}

	fmt.Println()
	fmt.Println("Waiting for server response ...")

	data := graphData(benchResults, oBenchNames, oBenchArgs)

	graphUrl, err := uploadData(*apiUrl, string(data), *title)
	if err != nil {
		fmt.Fprintf(os.Stderr, "uploading data: %v", err)
		os.Exit(1)
	}

	fmt.Println("=========================================")
	fmt.Println()
	fmt.Println(graphUrl)
	fmt.Println()
	fmt.Println("=========================================")

}