diff --git a/ci/Jenkinsfile b/ci/Jenkinsfile index 02676b378b2..bac72a4d48f 100644 --- a/ci/Jenkinsfile +++ b/ci/Jenkinsfile @@ -68,6 +68,9 @@ def gobuild_step(list) { } } +def benchNodeAddr +def benchJsonHash + /* PIPELINE */ ansiColor('xterm') { withEnv(['TERM=xterm-color']) { @@ -92,7 +95,7 @@ ansiColor('xterm') { withEnv(['TERM=xterm-color']) { timeout(time: check_timeout, unit: 'MINUTES') { gobuild_step(fast_build_platforms) } - } + }, ) } @@ -189,6 +192,13 @@ ansiColor('xterm') { withEnv(['TERM=xterm-color']) { } } }, + 'benchmark': { + setupStep('linux') { run -> + run 'make test/bench/bench-results.json' + + benchmark altInputSchema: '', altInputSchemaLocation: '', inputLocation: 'test/bench/bench-results.json', schemaSelection: 'defaultSchema', truncateStrings: false + } + }, ) } }} diff --git a/package.json b/package.json index bd5cf7bf61b..e138d625481 100644 --- a/package.json +++ b/package.json @@ -599,6 +599,12 @@ "hash": "QmTbBs3Y3u5F69XNJzdnnc6SP5GKgcXxCDzx6w8m6piVRT", "name": "go-bitfield", "version": "0.1.1" + }, + { + "author": "Magik6k", + "hash": "QmcpY7S3jQ47NhvLUQvSySpH5yPpYPpM6cfs9oGK6GkmW5", + "name": "tools", + "version": "1.0.3" } ], "gxVersion": "0.10.0", diff --git a/test/Rules.mk b/test/Rules.mk index e596dfd55a2..0bd810004df 100644 --- a/test/Rules.mk +++ b/test/Rules.mk @@ -1,5 +1,8 @@ include mk/header.mk +dir := $(d)/bench +include $(dir)/Rules.mk + dir := $(d)/bin include $(dir)/Rules.mk diff --git a/test/bench/.gitignore b/test/bench/.gitignore new file mode 100644 index 00000000000..1c3a48d0299 --- /dev/null +++ b/test/bench/.gitignore @@ -0,0 +1,2 @@ +bench-results.json +gobench.out diff --git a/test/bench/Rules.mk b/test/bench/Rules.mk new file mode 100644 index 00000000000..b6c02c411f7 --- /dev/null +++ b/test/bench/Rules.mk @@ -0,0 +1,12 @@ +include mk/header.mk + +DEPS_$(d) := test/bin/gobench-to-json + +$(d)/gobench.out: + go test -bench . -run '^Benchmark' ./... -benchmem | tee $(@D)/gobench.out +.PHONY: $(d)/gobench.out + +$(d)/bench-results.json: $$(DEPS_$(d)) $(d)/gobench.out + cat $(@D)/gobench.out | test/bin/gobench-to-json $(@D)/bench-results.json + +include mk/footer.mk diff --git a/test/bench/benchmark-plugin-schema.json b/test/bench/benchmark-plugin-schema.json new file mode 100644 index 00000000000..a4635ce089b --- /dev/null +++ b/test/bench/benchmark-plugin-schema.json @@ -0,0 +1,11 @@ +{ + "description": "Schema for gobench-to-json output", + "type": "array", + "items": { + "type": "object", + "properties": { + "Name": { "type": "name" }, + "" + } + } +} \ No newline at end of file diff --git a/test/bin/Rules.mk b/test/bin/Rules.mk index 279b59f21a8..f10b9e17957 100644 --- a/test/bin/Rules.mk +++ b/test/bin/Rules.mk @@ -26,6 +26,10 @@ $(d)/ma-pipe-unidir: test/dependencies/ma-pipe-unidir $(go-build) TGTS_$(d) += $(d)/ma-pipe-unidir +$(d)/gobench-to-json: test/dependencies/gobench-to-json + $(go-build) +TGTS_$(d) += $(d)/gobench-to-json + TGTS_GX_$(d) := hang-fds iptb TGTS_GX_$(d) := $(addprefix $(d)/,$(TGTS_GX_$(d))) diff --git a/test/dependencies/gobench-to-json/main.go b/test/dependencies/gobench-to-json/main.go new file mode 100644 index 00000000000..5927ded218f --- /dev/null +++ b/test/dependencies/gobench-to-json/main.go @@ -0,0 +1,131 @@ +package main + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "os" + + "gx/ipfs/QmcpY7S3jQ47NhvLUQvSySpH5yPpYPpM6cfs9oGK6GkmW5/tools/benchmark/parse" +) + +type Result struct { + Name string `json:"name"` + Description string `json:"description"` + + Unit string `json:"unit"` + DblValue float64 `json:"dblValue"` +} + +type Parameter struct { + Name string `json:"name"` + Description string `json:"description"` + + Unit string `json:"unit"` + Value interface{} `json:"value"` +} + +type Test struct { + Name string `json:"name"` + Description string `json:"description"` + + Parameters []Parameter `json:"parameters,omitempty"` + Results []Result `json:"results,omitempty"` +} + +type Group struct { + Name string `json:"name"` + Description string `json:"description"` + + Tests []Test `json:"tests"` +} + +type Out struct { + Groups []Group `json:"groups"` +} + +func main() { + if err := mainErr(); err != nil { + fmt.Fprintf(os.Stderr, "error: %s\n", err) + os.Exit(1) + } +} + +func mainErr() error { + if len(os.Args) != 2 { + return errors.New("usage: gobench-to-json [outfile]") + } + + benches, err := parse.ParseSet(os.Stdin) + if err != nil { + return err + } + + tests := make([]Test, 0, len(benches)) + for _, b := range benches { + for _, bench := range b { + results := make([]Result, 0, 4) + + if bench.Measured&parse.NsPerOp != 0 { + results = append(results, Result{ + Name: "time/op", + Description: "time per operation", + Unit: "ns", + DblValue: bench.NsPerOp, + }) + } + + if bench.Measured&parse.MBPerS != 0 { + results = append(results, Result{ + Name: "throughput", + Description: "throughput", + Unit: "MB/s", + DblValue: bench.MBPerS, + }) + } + + if bench.Measured&parse.AllocsPerOp != 0 { + results = append(results, Result{ + Name: "allocs/op", + Description: "number of allocations per operation", + Unit: "", + DblValue: float64(bench.AllocsPerOp), //TODO: figure out a better way + }) + } + + if bench.Measured&parse.AllocedBytesPerOp != 0 { + results = append(results, Result{ + Name: "alloc B/op", + Description: "bytes allocated per operation", + Unit: "B", + DblValue: float64(bench.AllocedBytesPerOp), //TODO: figure out a better way + }) + } + + tests = append(tests, Test{ + Name: bench.Name, + + Results: results, + }) + } + } + + out := Out{ + Groups: []Group{ + { + Name: "go", + Description: "gobench", + + Tests: tests, + }, + }, + } + + b, err := json.Marshal(&out) + if err != nil { + return err + } + + return ioutil.WriteFile(os.Args[1], b, 0664) +}